aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore153
-rw-r--r--README5
-rw-r--r--README.win3214
-rw-r--r--bootstrap/bin/start.bootbin5312 -> 5312 bytes
-rw-r--r--bootstrap/bin/start.script8
-rw-r--r--bootstrap/bin/start_clean.bootbin5312 -> 5312 bytes
-rw-r--r--bootstrap/bin/start_clean.script8
-rw-r--r--bootstrap/lib/compiler/ebin/beam_asm.beambin9032 -> 9168 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_block.beambin13416 -> 13096 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bool.beambin15148 -> 14928 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bsm.beambin12612 -> 12292 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_clean.beambin10336 -> 10192 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dead.beambin11228 -> 10908 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dict.beambin4248 -> 3928 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_disasm.beambin23500 -> 23204 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_flatten.beambin3632 -> 3312 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_jump.beambin9316 -> 8996 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_listing.beambin3040 -> 2720 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_opcodes.beambin6956 -> 6680 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_peep.beambin3496 -> 3176 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_trim.beambin8084 -> 7764 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_type.beambin13664 -> 13344 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin13416 -> 13096 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_validator.beambin31720 -> 31484 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl.beambin28644 -> 28432 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_clauses.beambin2964 -> 2644 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_inline.beambin33392 -> 33048 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_trees.beambin16168 -> 15848 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compile.beambin31412 -> 31092 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app2
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.appup2
-rw-r--r--bootstrap/lib/compiler/ebin/core_lib.beambin5376 -> 5056 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_lint.beambin10980 -> 10660 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_parse.beambin42016 -> 34380 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_pp.beambin11524 -> 11204 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_scan.beambin6596 -> 6276 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/erl_bifs.beambin2344 -> 2024 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/rec_env.beambin4732 -> 4412 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_dsetel.beambin6672 -> 6352 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_fold.beambin41916 -> 41596 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_inline.beambin4348 -> 4028 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_expand_pmod.beambin7748 -> 7428 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_pre_attributes.beambin3348 -> 3028 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_pre_expand.beambin14540 -> 14116 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin48336 -> 48016 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin45812 -> 45492 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel.beambin41680 -> 41256 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel_pp.beambin10980 -> 10660 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_life.beambin21236 -> 20916 bytes
-rw-r--r--bootstrap/lib/compiler/egen/beam_opcodes.erl10
-rw-r--r--bootstrap/lib/compiler/egen/beam_opcodes.hrl4
-rw-r--r--bootstrap/lib/compiler/egen/core_parse.erl2
-rw-r--r--bootstrap/lib/kernel/ebin/application.beambin2904 -> 2684 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_controller.beambin28916 -> 28696 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_master.beambin6160 -> 5940 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_starter.beambin1480 -> 1260 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/auth.beambin6132 -> 5912 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code.beambin5940 -> 5720 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code_server.beambin22412 -> 23852 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin37492 -> 37120 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_1.beambin23116 -> 22836 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_server.beambin6248 -> 5952 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_sup.beambin772 -> 552 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_ac.beambin24972 -> 24808 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_util.beambin9656 -> 9436 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_boot_server.beambin5492 -> 5272 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_ddll.beambin2676 -> 2456 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_distribution.beambin1968 -> 1748 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_epmd.beambin8020 -> 7668 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_reply.beambin1088 -> 868 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/error_handler.beambin2084 -> 1864 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/error_logger.beambin4304 -> 4084 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erts_debug.beambin2860 -> 2640 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin11232 -> 11012 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file_io_server.beambin13056 -> 12836 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file_server.beambin5072 -> 4852 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/gen_sctp.beambin3144 -> 2924 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/gen_tcp.beambin2404 -> 2184 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/gen_udp.beambin1656 -> 1436 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global.beambin31016 -> 30796 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global_group.beambin16516 -> 16296 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global_search.beambin2988 -> 2768 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin10744 -> 10580 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/heart.beambin3864 -> 3644 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/hipe_unified_loader.beambin11236 -> 11012 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin18208 -> 17988 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_sctp.beambin1216 -> 996 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp.beambin2744 -> 2524 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp_dist.beambin6012 -> 5792 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_udp.beambin1860 -> 1640 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_config.beambin8524 -> 8304 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_db.beambin24648 -> 24428 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_dns.beambin18988 -> 18484 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_gethost_native.beambin9748 -> 9528 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_hosts.beambin2236 -> 2016 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin11284 -> 11064 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_res.beambin14616 -> 14260 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_sctp.beambin1904 -> 1684 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp.beambin2552 -> 2332 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp_dist.beambin6332 -> 6112 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_udp.beambin2032 -> 1812 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.app2
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.appup2
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.beambin3784 -> 3564 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel_config.beambin2792 -> 2572 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net.beambin804 -> 584 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net_adm.beambin3084 -> 2864 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net_kernel.beambin21268 -> 21048 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/os.beambin4460 -> 4240 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/packages.beambin2320 -> 2100 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/pg2.beambin7160 -> 6940 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/ram_file.beambin6304 -> 6084 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/rpc.beambin8420 -> 8200 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/seq_trace.beambin1476 -> 1256 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/standard_error.beambin3692 -> 3472 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user.beambin11544 -> 11272 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user_drv.beambin9700 -> 9480 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user_sup.beambin1896 -> 1676 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/wrap_log_reader.beambin3440 -> 3220 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/array.beambin11004 -> 10720 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/base64.beambin4120 -> 3836 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/beam_lib.beambin16452 -> 16168 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin12932 -> 12664 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/calendar.beambin4520 -> 4236 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin49496 -> 49020 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_server.beambin6784 -> 6432 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_sup.beambin824 -> 540 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_utils.beambin26644 -> 26024 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v8.beambin26108 -> 25492 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin47348 -> 46524 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dict.beambin8880 -> 8596 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph.beambin7968 -> 7684 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph_utils.beambin6512 -> 6228 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin.beambin7208 -> 6924 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin_expand.beambin2916 -> 2632 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin20988 -> 20704 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_bits.beambin2752 -> 2468 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_compile.beambin5028 -> 4744 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin21908 -> 21624 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_expand_records.beambin17440 -> 17156 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_internal.beambin4196 -> 3912 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin72084 -> 72504 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_parse.beambin73136 -> 61804 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_posix_msg.beambin5192 -> 4908 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_pp.beambin21472 -> 21224 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin30832 -> 30300 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_tar.beambin14932 -> 14648 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_file_h.beambin4880 -> 4596 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_tty_h.beambin4616 -> 4332 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/escript.beambin12556 -> 12272 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin18800 -> 18516 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/eval_bits.beambin6424 -> 6140 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/file_sorter.beambin29028 -> 28588 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filelib.beambin6592 -> 6308 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filename.beambin8956 -> 8672 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gb_sets.beambin7804 -> 7520 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gb_trees.beambin4896 -> 4612 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen.beambin3740 -> 3456 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_event.beambin12144 -> 11880 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_fsm.beambin8828 -> 8600 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_server.beambin11620 -> 11336 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io.beambin6460 -> 6176 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib.beambin8468 -> 8308 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_format.beambin11232 -> 10948 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_fread.beambin7120 -> 6836 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_pretty.beambin11564 -> 11280 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lib.beambin8388 -> 8104 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lists.beambin28620 -> 27512 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/log_mf_h.beambin2660 -> 2376 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/math.beambin580 -> 296 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ms_transform.beambin17168 -> 16884 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/orddict.beambin2904 -> 2620 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ordsets.beambin2092 -> 1808 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/otp_internal.beambin7456 -> 7144 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/pg.beambin2220 -> 1936 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/pool.beambin3804 -> 3520 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proc_lib.beambin8760 -> 8476 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proplists.beambin4860 -> 4576 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin64816 -> 64584 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin66412 -> 66128 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/queue.beambin5908 -> 5552 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/random.beambin1684 -> 1400 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/re.beambin11668 -> 11384 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/regexp.beambin8180 -> 7896 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sets.beambin7020 -> 6736 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin27700 -> 27416 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell_default.beambin3800 -> 3516 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/slave.beambin4372 -> 4088 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin39920 -> 39096 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.app2
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.appup2
-rw-r--r--bootstrap/lib/stdlib/ebin/string.beambin4608 -> 4324 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor.beambin14312 -> 14028 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor_bridge.beambin2256 -> 1972 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sys.beambin7016 -> 6860 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/timer.beambin5120 -> 4836 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/unicode.beambin11076 -> 10792 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/win32reg.beambin5576 -> 5292 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/zip.beambin24244 -> 23960 bytes
-rw-r--r--bootstrap/lib/stdlib/egen/erl_parse.erl2
-rw-r--r--erts/.gitignore22
-rw-r--r--erts/aclocal.m4132
-rw-r--r--erts/configure.in210
-rw-r--r--erts/doc/src/erl_dist_protocol.xml12
-rw-r--r--erts/doc/src/erl_nif.xml196
-rw-r--r--erts/doc/src/erlang.xml15
-rw-r--r--erts/emulator/Makefile.in2
-rw-r--r--erts/emulator/beam/beam_emu.c95
-rw-r--r--erts/emulator/beam/break.c2
-rw-r--r--erts/emulator/beam/erl_nif.c154
-rw-r--r--erts/emulator/beam/erl_nif.h16
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h24
-rw-r--r--erts/emulator/beam/erl_process.c2
-rw-r--r--erts/emulator/beam/erl_process.h7
-rw-r--r--erts/emulator/beam/global.h3
-rw-r--r--erts/emulator/beam/sys.h5
-rw-r--r--erts/emulator/drivers/common/inet_drv.c4
-rw-r--r--erts/emulator/test/nif_SUITE.erl63
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c189
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.c6
-rw-r--r--erts/emulator/test/trace_nif_SUITE_data/trace_nif.c6
-rwxr-xr-xerts/emulator/utils/beam_makeops4
-rw-r--r--erts/epmd/src/epmd_int.h11
-rw-r--r--erts/epmd/src/epmd_srv.c28
-rw-r--r--erts/etc/unix/to_erl.c6
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/mc.sh8
-rwxr-xr-xerts/etc/win32/cygwin_tools/vc/rc.sh4
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin48420 -> 48420 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin23232 -> 23284 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44460 -> 44416 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1392 -> 1392 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin29480 -> 29480 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57308 -> 57308 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin20756 -> 20756 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10624 -> 10624 bytes
-rw-r--r--erts/preloaded/src/erlang.erl3
-rw-r--r--erts/preloaded/src/init.erl5
-rw-r--r--lib/.gitignore471
-rw-r--r--lib/asn1/doc/src/Makefile4
-rw-r--r--lib/asn1/doc/src/note.gifbin1539 -> 0 bytes
-rw-r--r--lib/asn1/doc/src/notes_history.xml1782
-rw-r--r--lib/asn1/doc/src/part_notes.xml39
-rw-r--r--lib/asn1/doc/src/warning.gifbin1498 -> 0 bytes
-rw-r--r--lib/compiler/src/beam_asm.erl2
-rw-r--r--lib/compiler/src/beam_bool.erl27
-rw-r--r--lib/compiler/test/andor_SUITE.erl66
-rw-r--r--lib/compiler/test/compilation_SUITE_data/on_load.erl2
-rw-r--r--lib/cosEvent/doc/src/Makefile3
-rw-r--r--lib/cosEvent/doc/src/notes.xml14
-rw-r--r--lib/cosEvent/vsn.mk6
-rw-r--r--lib/cosEventDomain/doc/src/Makefile3
-rw-r--r--lib/cosEventDomain/doc/src/ch_event_domain_service.xml6
-rw-r--r--lib/cosEventDomain/doc/src/notes.xml18
-rw-r--r--lib/cosEventDomain/vsn.mk7
-rw-r--r--lib/cosFileTransfer/doc/src/Makefile3
-rw-r--r--lib/cosFileTransfer/doc/src/notes.xml14
-rw-r--r--lib/cosFileTransfer/vsn.mk6
-rw-r--r--lib/cosNotification/doc/src/Makefile3
-rw-r--r--lib/cosNotification/doc/src/ch_BNF.xml6
-rw-r--r--lib/cosNotification/doc/src/ch_example.xml2
-rw-r--r--lib/cosNotification/doc/src/notes.xml22
-rw-r--r--lib/cosNotification/vsn.mk8
-rw-r--r--lib/cosProperty/doc/src/Makefile3
-rw-r--r--lib/cosProperty/doc/src/notes.xml14
-rw-r--r--lib/cosProperty/vsn.mk6
-rw-r--r--lib/cosTime/doc/src/Makefile3
-rw-r--r--lib/cosTime/doc/src/notes.xml14
-rw-r--r--lib/cosTime/vsn.mk6
-rw-r--r--lib/cosTransactions/doc/src/Makefile3
-rw-r--r--lib/cosTransactions/doc/src/notes.xml14
-rw-r--r--lib/cosTransactions/vsn.mk6
-rw-r--r--lib/crypto/c_src/crypto_drv.c78
-rw-r--r--lib/crypto/doc/src/crypto.xml64
-rw-r--r--lib/crypto/src/crypto.erl25
-rw-r--r--lib/crypto/test/Makefile83
-rw-r--r--lib/crypto/test/blowfish_SUITE.erl210
-rw-r--r--lib/crypto/test/crypto.spec2
-rw-r--r--lib/crypto/test/crypto_SUITE.erl1110
-rw-r--r--lib/debugger/doc/src/Makefile2
-rw-r--r--lib/debugger/doc/src/part_notes.xml40
-rw-r--r--lib/debugger/doc/src/warning.gifbin1498 -> 0 bytes
-rw-r--r--lib/debugger/src/dbg_ui_mon.erl13
-rw-r--r--lib/debugger/src/dbg_wx_filedialog_win.erl15
-rw-r--r--lib/debugger/src/dbg_wx_mon.erl15
-rw-r--r--lib/debugger/src/dbg_wx_mon_win.erl12
-rwxr-xr-xlib/debugger/src/dbg_wx_trace_win.erl12
-rw-r--r--lib/debugger/src/dbg_wx_win.erl23
-rw-r--r--lib/erl_docgen/priv/xsl/db_eix.xsl206
-rw-r--r--lib/erl_docgen/priv/xsl/db_html.xsl2
-rw-r--r--lib/erl_interface/configure.in10
-rw-r--r--lib/erl_interface/doc/src/ei_connect.xml21
-rw-r--r--lib/erl_interface/include/ei.h6
-rw-r--r--lib/erl_interface/src/connect/ei_connect.c18
-rw-r--r--lib/erl_interface/src/decode/decode_skip.c1
-rw-r--r--lib/erl_interface/src/misc/ei_internal.h2
-rw-r--r--lib/erl_interface/test/Makefile78
-rw-r--r--lib/erl_interface/test/Makefile.src71
-rw-r--r--lib/erl_interface/test/README28
-rw-r--r--lib/erl_interface/test/all_SUITE_data/Makefile.first20
-rw-r--r--lib/erl_interface/test/all_SUITE_data/Makefile.src45
-rw-r--r--lib/erl_interface/test/all_SUITE_data/ei_runner.c400
-rw-r--r--lib/erl_interface/test/all_SUITE_data/ei_runner.h61
-rw-r--r--lib/erl_interface/test/all_SUITE_data/gccifier.c317
-rwxr-xr-xlib/erl_interface/test/all_SUITE_data/gccifier.sh26
-rw-r--r--lib/erl_interface/test/all_SUITE_data/init_tc.erl101
-rw-r--r--lib/erl_interface/test/all_SUITE_data/reclaim.h151
-rw-r--r--lib/erl_interface/test/all_SUITE_data/runner.c457
-rw-r--r--lib/erl_interface/test/all_SUITE_data/runner.h50
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE.erl151
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src45
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c224
-rw-r--r--lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c234
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE.erl218
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src46
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c289
-rw-r--r--lib/erl_interface/test/ei_connect_SUITE_data/einode.c158
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE.erl300
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src42
-rw-r--r--lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c548
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE.erl290
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src42
-rw-r--r--lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c229
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE.erl315
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src42
-rw-r--r--lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c466
-rw-r--r--lib/erl_interface/test/ei_format_SUITE.erl161
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/Makefile.src42
-rw-r--r--lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c184
-rw-r--r--lib/erl_interface/test/ei_print_SUITE.erl142
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/Makefile.src42
-rw-r--r--lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c175
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE.erl666
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src41
-rw-r--r--lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c767
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE.erl134
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src41
-rw-r--r--lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c202
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE.erl1136
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src50
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c166
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c1511
-rw-r--r--lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c129
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE.erl81
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src41
-rw-r--r--lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c485
-rw-r--r--lib/erl_interface/test/erl_format_SUITE.erl136
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/Makefile.src43
-rw-r--r--lib/erl_interface/test/erl_format_SUITE_data/format_test.c132
-rw-r--r--lib/erl_interface/test/erl_interface.dynspec18
-rw-r--r--lib/erl_interface/test/erl_interface.spec2
-rw-r--r--lib/erl_interface/test/erl_interface.spec.vxworks5
-rw-r--r--lib/erl_interface/test/erl_match_SUITE.erl288
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/Makefile.first21
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/Makefile.src42
-rw-r--r--lib/erl_interface/test/erl_match_SUITE_data/match_test.c113
-rw-r--r--lib/erl_interface/test/port_call_SUITE.erl106
-rw-r--r--lib/erl_interface/test/port_call_SUITE_data/Makefile.src39
-rw-r--r--lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c103
-rw-r--r--lib/erl_interface/test/runner.erl130
-rw-r--r--lib/ic/doc/src/Makefile3
-rw-r--r--lib/ic/doc/src/c-part.xml28
-rw-r--r--lib/ic/doc/src/ch_c_corba_env.xml2
-rw-r--r--lib/ic/doc/src/ch_c_mapping.xml24
-rw-r--r--lib/ic/doc/src/ch_erl_genserv.xml12
-rw-r--r--lib/ic/doc/src/ch_erl_plain.xml2
-rw-r--r--lib/ic/doc/src/ch_ic_protocol.xml36
-rw-r--r--lib/ic/doc/src/ch_java.xml8
-rw-r--r--lib/ic/doc/src/erl-part.xml28
-rw-r--r--lib/ic/doc/src/ic_c_protocol.xml28
-rw-r--r--lib/ic/doc/src/java-part.xml28
-rw-r--r--lib/ic/doc/src/notes.xml12
-rw-r--r--lib/ic/doc/src/old_notes.xml1565
-rw-r--r--lib/ic/vsn.mk5
-rw-r--r--lib/kernel/src/code_server.erl27
-rw-r--r--lib/kernel/src/pg2.erl17
-rw-r--r--lib/kernel/test/code_SUITE.erl87
-rw-r--r--lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl2
-rw-r--r--lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl2
-rw-r--r--lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl2
-rw-r--r--lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl2
-rw-r--r--lib/kernel/test/code_SUITE_data/on_load_errors/on_load_error.erl13
-rw-r--r--lib/observer/src/crashdump_viewer.erl3
-rw-r--r--lib/observer/src/crashdump_viewer.hrl1
-rw-r--r--lib/observer/src/crashdump_viewer_html.erl2
-rw-r--r--lib/orber/doc/src/Makefile6
-rw-r--r--lib/orber/doc/src/ch_contents.xml4
-rw-r--r--lib/orber/doc/src/ch_example.xml2
-rw-r--r--lib/orber/doc/src/ch_idl_to_erlang_mapping.xml56
-rw-r--r--lib/orber/doc/src/ch_install.xml6
-rw-r--r--lib/orber/doc/src/ch_interceptors.xml22
-rw-r--r--lib/orber/doc/src/ch_naming_service.xml18
-rw-r--r--lib/orber/doc/src/corba.xml5
-rw-r--r--lib/orber/doc/src/notes.xml20
-rw-r--r--lib/orber/doc/src/notes_history.xml1523
-rw-r--r--lib/orber/doc/src/orber.xml2
-rw-r--r--lib/orber/doc/src/part_notes.xml2
-rw-r--r--lib/orber/doc/src/part_notes_history.xml38
-rw-r--r--lib/orber/vsn.mk7
-rw-r--r--lib/percept/src/egd.erl8
-rw-r--r--lib/percept/src/egd_font.erl7
-rw-r--r--[-rwxr-xr-x]lib/percept/src/egd_png.erl0
-rw-r--r--lib/percept/src/egd_primitives.erl138
-rw-r--r--lib/percept/src/egd_render.erl166
-rw-r--r--lib/percept/test/egd_SUITE.erl43
-rw-r--r--lib/public_key/doc/src/cert_records.xml34
-rw-r--r--lib/ssh/doc/src/Makefile6
-rw-r--r--lib/ssh/doc/src/notes.xml15
-rw-r--r--lib/ssh/doc/src/notes_history.xml737
-rw-r--r--lib/ssh/doc/src/part_notes.xml3
-rw-r--r--lib/ssh/doc/src/part_notes_history.xml36
-rw-r--r--lib/ssh/vsn.mk6
-rw-r--r--lib/ssl/doc/src/create_certs.xml14
-rw-r--r--lib/ssl/doc/src/new_ssl.xml23
-rw-r--r--lib/ssl/doc/src/pkix_certs.xml213
-rw-r--r--lib/ssl/doc/src/remember.xml83
-rw-r--r--lib/ssl/doc/src/ssl.xml35
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml30
-rw-r--r--lib/stdlib/doc/src/gen_server.xml29
-rw-r--r--lib/stdlib/doc/src/sys.xml39
-rw-r--r--lib/stdlib/src/c.erl4
-rw-r--r--lib/stdlib/src/gen_fsm.erl7
-rw-r--r--lib/stdlib/src/otp_internal.erl4
-rw-r--r--lib/stdlib/src/sys.erl11
-rw-r--r--lib/stdlib/test/c_SUITE.erl69
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl16
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl29
-rw-r--r--lib/tools/doc/src/notes.xml15
-rw-r--r--lib/tools/emacs/erlang.el117
-rw-r--r--lib/tools/emacs/test.erl.indented56
-rw-r--r--lib/tools/emacs/test.erl.orig50
-rw-r--r--lib/tools/src/cover.erl4
-rw-r--r--lib/tools/vsn.mk2
-rw-r--r--lib/wx/api_gen/wxapi.conf4
-rw-r--r--lib/wx/c_src/gen/wxe_funcs.cpp12
-rwxr-xr-xlib/wx/configure.in20
-rw-r--r--lib/wx/doc/src/Makefile10
-rw-r--r--lib/wx/doc/src/ref_man.xml.src (renamed from lib/wx/doc/src/ref_man.src.xml)0
-rw-r--r--lib/wx/src/gen/wxFileDialog.erl13
-rw-r--r--make/otp_release_targets.mk44
-rw-r--r--make/otp_subdir.mk20
-rwxr-xr-xotp_build165
-rw-r--r--system/doc/reference_manual/code_loading.xml35
-rw-r--r--system/doc/reference_manual/modules.xml15
-rw-r--r--xcomp/README218
-rw-r--r--xcomp/README.xcomp25
-rw-r--r--xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf166
-rw-r--r--xcomp/erl-xcomp-vxworks_ppc32.conf172
-rw-r--r--xcomp/erl-xcomp.conf.template174
460 files changed, 18311 insertions, 7556 deletions
diff --git a/.gitignore b/.gitignore
index 0207d07dfe..06d7e3a124 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,24 @@
# Match at any level.
*~
autom4te.cache
+*.beam
+*.asn1db
+
+!/bootstrap/lib/compiler/ebin/*.beam
+!/bootstrap/lib/kernel/ebin/*.beam
+!/bootstrap/lib/stdlib/ebin/*.beam
+!/erts/preloaded/ebin/*.beam
+!/lib/*/test/*_SUITE_data/*.beam
# Anchored from $ERL_TOP
/bin
+/config.log
+/config.status
-/lib/*/ebin
+/bootstrap/bin/*
+!/bootstrap/bin/*.script
+!/bootstrap/bin/*.boot
-/bootstrap/bin
/bootstrap/lib/asn1
/bootstrap/lib/hipe
/bootstrap/lib/ic
@@ -21,3 +32,141 @@ autom4te.cache
/configure
/release
+
+# General patterns for applications in lib.
+#
+# Assume that all test/Emakefiles are generated.
+#
+# Any application with a checked-in test/Emakefile should
+# use a negative pattern in its own .gitignore.
+
+/lib/*/ebin/*.app
+/lib/*/ebin/*.appup
+
+/lib/*/test/Emakefile
+
+/lib/configure
+/lib/config.log
+/lib/config.status
+
+#
+# Files generated by configure.
+#
+
+/lib/*/configure
+/lib/*/config.log
+/lib/*/config.status
+
+# common_test
+
+/lib/common_test/priv/install.sh
+
+# compiler
+/lib/compiler/src/beam_opcodes.erl
+/lib/compiler/src/beam_opcodes.hrl
+/lib/compiler/src/core_parse.erl
+
+/lib/compiler/test/*_r11_SUITE.erl
+/lib/compiler/test/*_no_opt_SUITE.erl
+/lib/compiler/test/*_post_opt_SUITE.erl
+
+# edoc
+
+/lib/edoc/priv/edoc_generate
+
+# gs
+
+/lib/gs/src/gstk_generic.hrl
+/lib/gs/contribs/ebin/*.gif
+/lib/gs/contribs/ebin/*.tool
+
+# hipe
+
+/lib/hipe/main/hipe.hrl
+
+# ic
+
+/lib/ic/examples/pre_post_condition/m.hrl
+/lib/ic/examples/pre_post_condition/m_i.erl
+/lib/ic/examples/pre_post_condition/m_i.hrl
+/lib/ic/examples/pre_post_condition/m_NotAnInteger.erl
+/lib/ic/examples/pre_post_condition/oe_ex.erl
+/lib/ic/examples/pre_post_condition/oe_ex.hrl
+/lib/ic/priv/com/
+/lib/ic/priv/ic.jar
+/lib/ic/src/icparse.erl
+
+# jinterface
+
+/lib/jinterface/priv/OtpErlang.jar
+/lib/jinterface/priv/com/
+
+# kernel
+
+/lib/kernel/src/inet_dns_record_adts.hrl
+
+# otp_mibs
+
+/lib/otp_mibs/include/[A-Z]*.hrl
+/lib/otp_mibs/mibs/v1/OTP*.mib.v1
+/lib/otp_mibs/priv/mibs/OTP*.bin
+
+# os_mon
+
+/lib/os_mon/include/[A-Z]*.hrl
+/lib/os_mon/mibs/v1/OTP*.mib.v1
+/lib/os_mon/priv/mibs/OTP*.bin
+
+# public_key
+
+/lib/public_key/asn1/*.asn1db
+/lib/public_key/asn1/*.erl
+/lib/public_key/asn1/*.hrl
+/lib/public_key/include/OTP-PUB-KEY.hrl
+
+# ssh
+
+/lib/ssh/src/*.asn1db
+/lib/ssh/src/DSS.erl
+/lib/ssh/src/DSS.hrl
+/lib/ssh/src/PKCS-1.erl
+/lib/ssh/src/PKCS-1.hrl
+
+# ssl
+
+/lib/ssl/pkix/*.asn1db
+/lib/ssl/examples/certs/done
+/lib/ssl/examples/certs/ebin/make_certs.beam
+/lib/ssl/examples/certs/etc/
+/lib/ssl/include/OTP-PKIX.hrl
+/lib/ssl/pkix/OTP-PKIX.erl
+/lib/ssl/pkix/OTP-PKIX.hrl
+/lib/ssl/pkix/ssl_pkix_oid.erl
+
+# snmp
+
+/lib/snmp/bin/snmp-v2tov1
+/lib/snmp/examples/ex1/EX1-MIB.bin
+/lib/snmp/mibs/Makefile
+/lib/snmp/mibs/v1/OTP-SNMPEA-MIB.mib.v1
+/lib/snmp/src/compile/snmpc_mib_gram.erl
+/lib/snmp/include/[A-Z]*.hrl
+/lib/snmp/priv/mibs/[A-Z]*.bin
+
+# test_server
+/lib/test_server/src/configure
+
+# wx
+/lib/wx/c_src/Makefile
+/lib/wx/config.mk
+/lib/wx/api_gen/wx_xml/*
+/lib/wx/api_gen/gl_xml/*
+/lib/wx/api_gen/??_doxygen
+/lib/wx/api_gen/??xml_generated
+/lib/wx/wx-*.ez
+
+# xmerl
+
+/lib/xmerl/src/xmerl_sax_parser_*.erl
+/lib/xmerl/src/xmerl_b64Bin.erl
+/lib/xmerl/src/xmerl_xpath_parse.erl
diff --git a/README b/README
index 51a9ddb756..260e9fd36b 100644
--- a/README
+++ b/README
@@ -243,6 +243,11 @@ if './otp_build remove_prebuilt_files' is invoked.
If you or your system has special requirements please read the
Makefile for additional configuration information.
+Cross compiling Erlang/OTP
+--------------------------
+The support for cross compiling Erlang/OTP is in its early stage of
+development, and should be considered as experimental. For more
+information see: $ERL_TOP/xcomp/README
How to build a debug enabled Erlang runtime system
--------------------------------------------------
diff --git a/README.win32 b/README.win32
index a6d2609aae..6fd14b23dc 100644
--- a/README.win32
+++ b/README.win32
@@ -366,6 +366,20 @@ backslashes in your path environment variable in Cygwin bash, but LIB
and INCLUDE should contain Windows style paths with semicolon,
drive letters and backslashes.
+If you wish to use Visual Studio 2008, a couple things need to be tweaked,
+namely the fact that some of the SDK stuff is installed in (by default)
+C:\Program Files\Microsoft SDKs\v6.0A . Just ensure that that
+C:\Program Files\Microsoft SDKs\v6.0A\Lib is in LIB and
+C:\Program Files\Microsoft SDKs\v6.0A\Include is in INCLUDE. A symptom of not
+doing this is errors about finding kernel32.lib and windows.h.
+
+Additionally, if you encounter errors about mc.exe not being found, you must
+install the entire Windows SDK (the partial SDK included in visual studio
+apparently does not include it). After installing it you'll want to add
+something like: /c/cygdrive/Program\ Files/Microsoft\ SDKs/v7.0/bin to your
+PATH to allow the environment to find mc.exe. The next Visual Studio (2010) is
+expected to include this tool.
+
* Sun's Java JDK 1.5.0 or higher. Our Java code (jinterface, ic) is
written for JDK 1.5.0. Get it for Windows and install it, the JRE is
not enough. If you don't care about Java, you can skip this step, the
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot
index c64535c35f..4153fa1087 100644
--- a/bootstrap/bin/start.boot
+++ b/bootstrap/bin/start.boot
Binary files differ
diff --git a/bootstrap/bin/start.script b/bootstrap/bin/start.script
index a9a0de4d7f..61a0942632 100644
--- a/bootstrap/bin/start.script
+++ b/bootstrap/bin/start.script
@@ -1,6 +1,6 @@
-%% script generated at {2009,11,16} {16,51,54}
+%% script generated at {2009,12,14} {14,9,55}
{script,
- {"OTP APN 181 01","R13B03"},
+ {"OTP APN 181 01","R13B04"},
[{preLoaded,
[erl_prim_loader,erlang,init,otp_ring0,prim_file,prim_inet,prim_zip,
zlib]},
@@ -43,7 +43,7 @@
{application_controller,start,
[{application,kernel,
[{description,"ERTS CXC 138 10"},
- {vsn,"2.13.4"},
+ {vsn,"2.13.5"},
{id,[]},
{modules,
[application,application_controller,application_master,
@@ -80,7 +80,7 @@
{application,load,
[{application,stdlib,
[{description,"ERTS CXC 138 10"},
- {vsn,"1.16.4"},
+ {vsn,"1.16.5"},
{id,[]},
{modules,
[array,base64,beam_lib,c,calendar,dets,dets_server,
diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot
index c64535c35f..4153fa1087 100644
--- a/bootstrap/bin/start_clean.boot
+++ b/bootstrap/bin/start_clean.boot
Binary files differ
diff --git a/bootstrap/bin/start_clean.script b/bootstrap/bin/start_clean.script
index a9a0de4d7f..61a0942632 100644
--- a/bootstrap/bin/start_clean.script
+++ b/bootstrap/bin/start_clean.script
@@ -1,6 +1,6 @@
-%% script generated at {2009,11,16} {16,51,54}
+%% script generated at {2009,12,14} {14,9,55}
{script,
- {"OTP APN 181 01","R13B03"},
+ {"OTP APN 181 01","R13B04"},
[{preLoaded,
[erl_prim_loader,erlang,init,otp_ring0,prim_file,prim_inet,prim_zip,
zlib]},
@@ -43,7 +43,7 @@
{application_controller,start,
[{application,kernel,
[{description,"ERTS CXC 138 10"},
- {vsn,"2.13.4"},
+ {vsn,"2.13.5"},
{id,[]},
{modules,
[application,application_controller,application_master,
@@ -80,7 +80,7 @@
{application,load,
[{application,stdlib,
[{description,"ERTS CXC 138 10"},
- {vsn,"1.16.4"},
+ {vsn,"1.16.5"},
{id,[]},
{modules,
[array,base64,beam_lib,c,calendar,dets,dets_server,
diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam
index 4c344fb55b..1c2783cc14 100644
--- a/bootstrap/lib/compiler/ebin/beam_asm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_asm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_block.beam b/bootstrap/lib/compiler/ebin/beam_block.beam
index 4aec75add0..2b2b569026 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 36ea808338..d286fb2f5b 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_bsm.beam b/bootstrap/lib/compiler/ebin/beam_bsm.beam
index 5134dae164..73b165e574 100644
--- a/bootstrap/lib/compiler/ebin/beam_bsm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_bsm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_clean.beam b/bootstrap/lib/compiler/ebin/beam_clean.beam
index fd6502fd3f..d43e6210bf 100644
--- a/bootstrap/lib/compiler/ebin/beam_clean.beam
+++ b/bootstrap/lib/compiler/ebin/beam_clean.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_dead.beam b/bootstrap/lib/compiler/ebin/beam_dead.beam
index fc938961d2..bdba7d1bfd 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 88949a4d5f..61d74bb393 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_disasm.beam b/bootstrap/lib/compiler/ebin/beam_disasm.beam
index 61f2255751..9b43e250c0 100644
--- a/bootstrap/lib/compiler/ebin/beam_disasm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_disasm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_flatten.beam b/bootstrap/lib/compiler/ebin/beam_flatten.beam
index 9a9bfbeba6..b8ed6402bf 100644
--- a/bootstrap/lib/compiler/ebin/beam_flatten.beam
+++ b/bootstrap/lib/compiler/ebin/beam_flatten.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_jump.beam b/bootstrap/lib/compiler/ebin/beam_jump.beam
index 3d7e8743b1..523c7bfefe 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_listing.beam b/bootstrap/lib/compiler/ebin/beam_listing.beam
index daa551e458..a68dd78e6c 100644
--- a/bootstrap/lib/compiler/ebin/beam_listing.beam
+++ b/bootstrap/lib/compiler/ebin/beam_listing.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_opcodes.beam b/bootstrap/lib/compiler/ebin/beam_opcodes.beam
index d3d8d2f9bb..adbcacff53 100644
--- a/bootstrap/lib/compiler/ebin/beam_opcodes.beam
+++ b/bootstrap/lib/compiler/ebin/beam_opcodes.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_peep.beam b/bootstrap/lib/compiler/ebin/beam_peep.beam
index 3bbceac19f..9fcb2536c8 100644
--- a/bootstrap/lib/compiler/ebin/beam_peep.beam
+++ b/bootstrap/lib/compiler/ebin/beam_peep.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_trim.beam b/bootstrap/lib/compiler/ebin/beam_trim.beam
index f6cf5d15e1..74b0cec2f6 100644
--- a/bootstrap/lib/compiler/ebin/beam_trim.beam
+++ b/bootstrap/lib/compiler/ebin/beam_trim.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_type.beam b/bootstrap/lib/compiler/ebin/beam_type.beam
index 31a6c465bb..3f281d5d01 100644
--- a/bootstrap/lib/compiler/ebin/beam_type.beam
+++ b/bootstrap/lib/compiler/ebin/beam_type.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam
index b66406ca68..51975f77d4 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 4d6742225e..832e473761 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/cerl.beam b/bootstrap/lib/compiler/ebin/cerl.beam
index c1ecd06293..b0fef4fd1a 100644
--- a/bootstrap/lib/compiler/ebin/cerl.beam
+++ b/bootstrap/lib/compiler/ebin/cerl.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_clauses.beam b/bootstrap/lib/compiler/ebin/cerl_clauses.beam
index 41ed5b6b54..662f42259f 100644
--- a/bootstrap/lib/compiler/ebin/cerl_clauses.beam
+++ b/bootstrap/lib/compiler/ebin/cerl_clauses.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_inline.beam b/bootstrap/lib/compiler/ebin/cerl_inline.beam
index a20bccbed9..30926f66ca 100644
--- a/bootstrap/lib/compiler/ebin/cerl_inline.beam
+++ b/bootstrap/lib/compiler/ebin/cerl_inline.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/cerl_trees.beam b/bootstrap/lib/compiler/ebin/cerl_trees.beam
index 66c5759506..49fb42c1c6 100644
--- a/bootstrap/lib/compiler/ebin/cerl_trees.beam
+++ b/bootstrap/lib/compiler/ebin/cerl_trees.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam
index d988dd86cf..1e711b2461 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 3d32ec6954..d5e7956176 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -18,7 +18,7 @@
{application, compiler,
[{description, "ERTS CXC 138 10"},
- {vsn, "4.6.3"},
+ {vsn, "4.6.4"},
{modules, [
beam_asm,
beam_block,
diff --git a/bootstrap/lib/compiler/ebin/compiler.appup b/bootstrap/lib/compiler/ebin/compiler.appup
index aa81bde536..224c761cc2 100644
--- a/bootstrap/lib/compiler/ebin/compiler.appup
+++ b/bootstrap/lib/compiler/ebin/compiler.appup
@@ -1 +1 @@
-{"4.6.3",[],[]}.
+{"4.6.4",[],[]}.
diff --git a/bootstrap/lib/compiler/ebin/core_lib.beam b/bootstrap/lib/compiler/ebin/core_lib.beam
index 8e0c11ab54..254d3375e0 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_lint.beam b/bootstrap/lib/compiler/ebin/core_lint.beam
index b944183f28..892268bc79 100644
--- a/bootstrap/lib/compiler/ebin/core_lint.beam
+++ b/bootstrap/lib/compiler/ebin/core_lint.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_parse.beam b/bootstrap/lib/compiler/ebin/core_parse.beam
index c8a3945ad9..19202ce827 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 dc0fcb477c..94baecf93c 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/core_scan.beam b/bootstrap/lib/compiler/ebin/core_scan.beam
index b920703e07..d9a088f4c6 100644
--- a/bootstrap/lib/compiler/ebin/core_scan.beam
+++ b/bootstrap/lib/compiler/ebin/core_scan.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/erl_bifs.beam b/bootstrap/lib/compiler/ebin/erl_bifs.beam
index add028e992..8132234cb1 100644
--- a/bootstrap/lib/compiler/ebin/erl_bifs.beam
+++ b/bootstrap/lib/compiler/ebin/erl_bifs.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/rec_env.beam b/bootstrap/lib/compiler/ebin/rec_env.beam
index 5eb4e658c4..9e3d93482e 100644
--- a/bootstrap/lib/compiler/ebin/rec_env.beam
+++ b/bootstrap/lib/compiler/ebin/rec_env.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam b/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam
index 8529721a53..28663aea47 100644
--- a/bootstrap/lib/compiler/ebin/sys_core_dsetel.beam
+++ b/bootstrap/lib/compiler/ebin/sys_core_dsetel.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 72b6fe41dc..cff47f2997 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 98b5aa587d..610f6e25cc 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/sys_expand_pmod.beam b/bootstrap/lib/compiler/ebin/sys_expand_pmod.beam
index 9affce0919..e755328d2d 100644
--- a/bootstrap/lib/compiler/ebin/sys_expand_pmod.beam
+++ b/bootstrap/lib/compiler/ebin/sys_expand_pmod.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam b/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
index 01e0b77e53..9708cff55e 100644
--- a/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
+++ b/bootstrap/lib/compiler/ebin/sys_pre_attributes.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/sys_pre_expand.beam b/bootstrap/lib/compiler/ebin/sys_pre_expand.beam
index 77720809bc..a5a0a3d6ac 100644
--- a/bootstrap/lib/compiler/ebin/sys_pre_expand.beam
+++ b/bootstrap/lib/compiler/ebin/sys_pre_expand.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam
index 7eafc0f119..4417a91407 100644
--- a/bootstrap/lib/compiler/ebin/v3_codegen.beam
+++ b/bootstrap/lib/compiler/ebin/v3_codegen.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_core.beam b/bootstrap/lib/compiler/ebin/v3_core.beam
index 3c8a67ee88..111753213e 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 683d004187..ca4bb278e1 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 e8fa77539b..c72919dc97 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/compiler/ebin/v3_life.beam b/bootstrap/lib/compiler/ebin/v3_life.beam
index b6b1885cfd..59a6797138 100644
--- a/bootstrap/lib/compiler/ebin/v3_life.beam
+++ b/bootstrap/lib/compiler/ebin/v3_life.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/egen/beam_opcodes.erl b/bootstrap/lib/compiler/egen/beam_opcodes.erl
index ea74760bb3..6adbe4c7c7 100644
--- a/bootstrap/lib/compiler/egen/beam_opcodes.erl
+++ b/bootstrap/lib/compiler/egen/beam_opcodes.erl
@@ -1,6 +1,6 @@
-module(beam_opcodes).
-%% Warning: Do not edit this file. It was automatically
-%% generated by 'beam_makeops' on Mon Nov 16 12:53:08 2009.
+%% Warning: Do not edit this file.
+%% Auto-generated by 'beam_makeops'.
-export([format_number/0]).
-export([opcode/2,opname/1]).
@@ -8,7 +8,7 @@
-spec format_number() -> 0.
format_number() -> 0.
--spec opcode(atom(), 0..8) -> 1..148.
+-spec opcode(atom(), 0..8) -> 1..149.
opcode(label, 1) -> 1;
opcode(func_info, 3) -> 2;
opcode(int_code_end, 0) -> 3;
@@ -157,9 +157,10 @@ opcode(bs_put_utf8, 3) -> 145;
opcode(bs_utf16_size, 3) -> 146;
opcode(bs_put_utf16, 3) -> 147;
opcode(bs_put_utf32, 3) -> 148;
+opcode(on_load, 0) -> 149;
opcode(Name, Arity) -> erlang:error(badarg, [Name,Arity]).
--spec opname(1..148) -> {atom(),0..8}.
+-spec opname(1..149) -> {atom(),0..8}.
opname(1) -> {label,1};
opname(2) -> {func_info,3};
opname(3) -> {int_code_end,0};
@@ -308,4 +309,5 @@ opname(145) -> {bs_put_utf8,3};
opname(146) -> {bs_utf16_size,3};
opname(147) -> {bs_put_utf16,3};
opname(148) -> {bs_put_utf32,3};
+opname(149) -> {on_load,0};
opname(Number) -> erlang:error(badarg, [Number]).
diff --git a/bootstrap/lib/compiler/egen/beam_opcodes.hrl b/bootstrap/lib/compiler/egen/beam_opcodes.hrl
index 0bb6a426c1..6ad7d17118 100644
--- a/bootstrap/lib/compiler/egen/beam_opcodes.hrl
+++ b/bootstrap/lib/compiler/egen/beam_opcodes.hrl
@@ -1,5 +1,5 @@
-%% Warning: Do not edit this file. It was automatically
-%% generated by 'beam_makeops' on Mon Nov 16 12:53:08 2009.
+%% Warning: Do not edit this file.
+%% Auto-generated by 'beam_makeops'.
-define(tag_u, 0).
-define(tag_i, 1).
diff --git a/bootstrap/lib/compiler/egen/core_parse.erl b/bootstrap/lib/compiler/egen/core_parse.erl
index 3ff8e05af3..f20cda3d04 100644
--- a/bootstrap/lib/compiler/egen/core_parse.erl
+++ b/bootstrap/lib/compiler/egen/core_parse.erl
@@ -13,7 +13,7 @@
tok_val(T) -> element(3, T).
tok_line(T) -> element(2, T).
--file("/usr/local/otp/releases/otp_beam_linux_sles10_i386_r13b02_patched/lib/parsetools-2.0/include/yeccpre.hrl", 0).
+-file("/usr/local/otp/releases/sles10_32_R13B03_patched/lib/parsetools-2.0.1/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
diff --git a/bootstrap/lib/kernel/ebin/application.beam b/bootstrap/lib/kernel/ebin/application.beam
index 86dd678c43..3414e8bcc4 100644
--- a/bootstrap/lib/kernel/ebin/application.beam
+++ b/bootstrap/lib/kernel/ebin/application.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam
index 29177d44e1..4cb6bc6b7e 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/application_master.beam b/bootstrap/lib/kernel/ebin/application_master.beam
index aa902b6c02..1d82fcd682 100644
--- a/bootstrap/lib/kernel/ebin/application_master.beam
+++ b/bootstrap/lib/kernel/ebin/application_master.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/application_starter.beam b/bootstrap/lib/kernel/ebin/application_starter.beam
index 580be006a4..542ef99f18 100644
--- a/bootstrap/lib/kernel/ebin/application_starter.beam
+++ b/bootstrap/lib/kernel/ebin/application_starter.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/auth.beam b/bootstrap/lib/kernel/ebin/auth.beam
index c547e567cd..9fc133efe7 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 176c79bf31..105de39d21 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 3fb6b1f97f..9515ff81c1 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 3d806e177d..86927f1125 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 239b1e7ee4..942e1188ac 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/disk_log_server.beam b/bootstrap/lib/kernel/ebin/disk_log_server.beam
index 021b1e68a2..46d7a9f546 100644
--- a/bootstrap/lib/kernel/ebin/disk_log_server.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log_sup.beam b/bootstrap/lib/kernel/ebin/disk_log_sup.beam
index 3d426eb8c3..a98998064d 100644
--- a/bootstrap/lib/kernel/ebin/disk_log_sup.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log_sup.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/dist_ac.beam b/bootstrap/lib/kernel/ebin/dist_ac.beam
index 25345c80d9..3060733116 100644
--- a/bootstrap/lib/kernel/ebin/dist_ac.beam
+++ b/bootstrap/lib/kernel/ebin/dist_ac.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/dist_util.beam b/bootstrap/lib/kernel/ebin/dist_util.beam
index 48497a8524..d823f8d5c6 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/erl_boot_server.beam b/bootstrap/lib/kernel/ebin/erl_boot_server.beam
index 6aed4ffb1d..52d638fb32 100644
--- a/bootstrap/lib/kernel/ebin/erl_boot_server.beam
+++ b/bootstrap/lib/kernel/ebin/erl_boot_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_ddll.beam b/bootstrap/lib/kernel/ebin/erl_ddll.beam
index 8728cc1027..81daa5376b 100644
--- a/bootstrap/lib/kernel/ebin/erl_ddll.beam
+++ b/bootstrap/lib/kernel/ebin/erl_ddll.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_distribution.beam b/bootstrap/lib/kernel/ebin/erl_distribution.beam
index 23e1b9ca19..d4e52d01a9 100644
--- a/bootstrap/lib/kernel/ebin/erl_distribution.beam
+++ b/bootstrap/lib/kernel/ebin/erl_distribution.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_epmd.beam b/bootstrap/lib/kernel/ebin/erl_epmd.beam
index 8d1b1ac016..9ba74e3303 100644
--- a/bootstrap/lib/kernel/ebin/erl_epmd.beam
+++ b/bootstrap/lib/kernel/ebin/erl_epmd.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_reply.beam b/bootstrap/lib/kernel/ebin/erl_reply.beam
index 23abde7ea3..97b027a67d 100644
--- a/bootstrap/lib/kernel/ebin/erl_reply.beam
+++ b/bootstrap/lib/kernel/ebin/erl_reply.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/error_handler.beam b/bootstrap/lib/kernel/ebin/error_handler.beam
index 42316bebf5..e97e1d214f 100644
--- a/bootstrap/lib/kernel/ebin/error_handler.beam
+++ b/bootstrap/lib/kernel/ebin/error_handler.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/error_logger.beam b/bootstrap/lib/kernel/ebin/error_logger.beam
index 2020fce100..c89e4d36c9 100644
--- a/bootstrap/lib/kernel/ebin/error_logger.beam
+++ b/bootstrap/lib/kernel/ebin/error_logger.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erts_debug.beam b/bootstrap/lib/kernel/ebin/erts_debug.beam
index 7f4c62ace8..26288e0633 100644
--- a/bootstrap/lib/kernel/ebin/erts_debug.beam
+++ b/bootstrap/lib/kernel/ebin/erts_debug.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/file.beam b/bootstrap/lib/kernel/ebin/file.beam
index 035cb98e00..0f11da59e1 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/file_io_server.beam b/bootstrap/lib/kernel/ebin/file_io_server.beam
index e59b45caab..93e19d9463 100644
--- a/bootstrap/lib/kernel/ebin/file_io_server.beam
+++ b/bootstrap/lib/kernel/ebin/file_io_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/file_server.beam b/bootstrap/lib/kernel/ebin/file_server.beam
index 50e2867373..7b9075b3ae 100644
--- a/bootstrap/lib/kernel/ebin/file_server.beam
+++ b/bootstrap/lib/kernel/ebin/file_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/gen_sctp.beam b/bootstrap/lib/kernel/ebin/gen_sctp.beam
index 9f0c1725c4..18ecaff05f 100644
--- a/bootstrap/lib/kernel/ebin/gen_sctp.beam
+++ b/bootstrap/lib/kernel/ebin/gen_sctp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/gen_tcp.beam b/bootstrap/lib/kernel/ebin/gen_tcp.beam
index 54ccc02e9d..fa87a6726b 100644
--- a/bootstrap/lib/kernel/ebin/gen_tcp.beam
+++ b/bootstrap/lib/kernel/ebin/gen_tcp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/gen_udp.beam b/bootstrap/lib/kernel/ebin/gen_udp.beam
index 8115d9f2de..5af947d638 100644
--- a/bootstrap/lib/kernel/ebin/gen_udp.beam
+++ b/bootstrap/lib/kernel/ebin/gen_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/global.beam b/bootstrap/lib/kernel/ebin/global.beam
index a458113179..6f576b3cb2 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/global_group.beam b/bootstrap/lib/kernel/ebin/global_group.beam
index ac5d1c3318..6e9d6e8dfd 100644
--- a/bootstrap/lib/kernel/ebin/global_group.beam
+++ b/bootstrap/lib/kernel/ebin/global_group.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/global_search.beam b/bootstrap/lib/kernel/ebin/global_search.beam
index 95a698ba11..8270772543 100644
--- a/bootstrap/lib/kernel/ebin/global_search.beam
+++ b/bootstrap/lib/kernel/ebin/global_search.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/group.beam b/bootstrap/lib/kernel/ebin/group.beam
index fb28b5d83e..8e75aaef55 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/heart.beam b/bootstrap/lib/kernel/ebin/heart.beam
index 1ace850784..5d5017225d 100644
--- a/bootstrap/lib/kernel/ebin/heart.beam
+++ b/bootstrap/lib/kernel/ebin/heart.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
index d3c41dd227..21d21208f3 100644
--- a/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
+++ b/bootstrap/lib/kernel/ebin/hipe_unified_loader.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam
index f4cef6d22a..d12f0a57a9 100644
--- a/bootstrap/lib/kernel/ebin/inet.beam
+++ b/bootstrap/lib/kernel/ebin/inet.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_sctp.beam b/bootstrap/lib/kernel/ebin/inet6_sctp.beam
index ba82ab572a..0e71998ed9 100644
--- a/bootstrap/lib/kernel/ebin/inet6_sctp.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_sctp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet6_tcp.beam b/bootstrap/lib/kernel/ebin/inet6_tcp.beam
index 37d381a23c..c573bc2821 100644
--- a/bootstrap/lib/kernel/ebin/inet6_tcp.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_tcp.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 3224a4364b..c83a3246eb 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/inet6_udp.beam b/bootstrap/lib/kernel/ebin/inet6_udp.beam
index 229a74076a..74cbff87c0 100644
--- a/bootstrap/lib/kernel/ebin/inet6_udp.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_config.beam b/bootstrap/lib/kernel/ebin/inet_config.beam
index 8092ed88ed..5b93d653f7 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 fcd69f8b57..14e0e57729 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_dns.beam b/bootstrap/lib/kernel/ebin/inet_dns.beam
index ebeb74e0f0..59e8936722 100644
--- a/bootstrap/lib/kernel/ebin/inet_dns.beam
+++ b/bootstrap/lib/kernel/ebin/inet_dns.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
index 089ce665e1..aaaecc8577 100644
--- a/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
+++ b/bootstrap/lib/kernel/ebin/inet_gethost_native.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_hosts.beam b/bootstrap/lib/kernel/ebin/inet_hosts.beam
index 04f3b8be5c..03a48175dd 100644
--- a/bootstrap/lib/kernel/ebin/inet_hosts.beam
+++ b/bootstrap/lib/kernel/ebin/inet_hosts.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam
index 2e37fba5b3..3315aab31f 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_res.beam b/bootstrap/lib/kernel/ebin/inet_res.beam
index fbbca5afca..3b6f72aaa0 100644
--- a/bootstrap/lib/kernel/ebin/inet_res.beam
+++ b/bootstrap/lib/kernel/ebin/inet_res.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_sctp.beam b/bootstrap/lib/kernel/ebin/inet_sctp.beam
index 190badd423..0372452973 100644
--- a/bootstrap/lib/kernel/ebin/inet_sctp.beam
+++ b/bootstrap/lib/kernel/ebin/inet_sctp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_tcp.beam b/bootstrap/lib/kernel/ebin/inet_tcp.beam
index f49abf5447..59abaedf6e 100644
--- a/bootstrap/lib/kernel/ebin/inet_tcp.beam
+++ b/bootstrap/lib/kernel/ebin/inet_tcp.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 94c08abebe..07f6ad2521 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/inet_udp.beam b/bootstrap/lib/kernel/ebin/inet_udp.beam
index f05dfda304..2ac9537087 100644
--- a/bootstrap/lib/kernel/ebin/inet_udp.beam
+++ b/bootstrap/lib/kernel/ebin/inet_udp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app
index fae87d3189..c6abc267b1 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -21,7 +21,7 @@
{application, kernel,
[
{description, "ERTS CXC 138 10"},
- {vsn, "2.13.4"},
+ {vsn, "2.13.5"},
{modules, [application,
application_controller,
application_master,
diff --git a/bootstrap/lib/kernel/ebin/kernel.appup b/bootstrap/lib/kernel/ebin/kernel.appup
index 2d1ae9302c..c5c34877ef 100644
--- a/bootstrap/lib/kernel/ebin/kernel.appup
+++ b/bootstrap/lib/kernel/ebin/kernel.appup
@@ -1 +1 @@
-{"2.13.4",[],[]}.
+{"2.13.5",[],[]}.
diff --git a/bootstrap/lib/kernel/ebin/kernel.beam b/bootstrap/lib/kernel/ebin/kernel.beam
index b7fe9fa50a..3eea9dda68 100644
--- a/bootstrap/lib/kernel/ebin/kernel.beam
+++ b/bootstrap/lib/kernel/ebin/kernel.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel_config.beam b/bootstrap/lib/kernel/ebin/kernel_config.beam
index 58ed8d19e6..b291058d1a 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.beam b/bootstrap/lib/kernel/ebin/net.beam
index fbadd77eb4..21df570be5 100644
--- a/bootstrap/lib/kernel/ebin/net.beam
+++ b/bootstrap/lib/kernel/ebin/net.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/net_adm.beam b/bootstrap/lib/kernel/ebin/net_adm.beam
index e5ad2e8665..02b6c8b486 100644
--- a/bootstrap/lib/kernel/ebin/net_adm.beam
+++ b/bootstrap/lib/kernel/ebin/net_adm.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/net_kernel.beam b/bootstrap/lib/kernel/ebin/net_kernel.beam
index cacbf28d42..50b4c7ac4c 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 74e824234b..aed29ac5ab 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/packages.beam b/bootstrap/lib/kernel/ebin/packages.beam
index b2f2f3876f..710fc55908 100644
--- a/bootstrap/lib/kernel/ebin/packages.beam
+++ b/bootstrap/lib/kernel/ebin/packages.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/pg2.beam b/bootstrap/lib/kernel/ebin/pg2.beam
index aab5132bab..efb224f375 100644
--- a/bootstrap/lib/kernel/ebin/pg2.beam
+++ b/bootstrap/lib/kernel/ebin/pg2.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/ram_file.beam b/bootstrap/lib/kernel/ebin/ram_file.beam
index 7f89c819b4..f9488df846 100644
--- a/bootstrap/lib/kernel/ebin/ram_file.beam
+++ b/bootstrap/lib/kernel/ebin/ram_file.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/rpc.beam b/bootstrap/lib/kernel/ebin/rpc.beam
index 714bbd974c..879f938be0 100644
--- a/bootstrap/lib/kernel/ebin/rpc.beam
+++ b/bootstrap/lib/kernel/ebin/rpc.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/seq_trace.beam b/bootstrap/lib/kernel/ebin/seq_trace.beam
index 138dabd4bc..ce4f50c6f3 100644
--- a/bootstrap/lib/kernel/ebin/seq_trace.beam
+++ b/bootstrap/lib/kernel/ebin/seq_trace.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/standard_error.beam b/bootstrap/lib/kernel/ebin/standard_error.beam
index bf0864d7ef..32554b1b73 100644
--- a/bootstrap/lib/kernel/ebin/standard_error.beam
+++ b/bootstrap/lib/kernel/ebin/standard_error.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/user.beam b/bootstrap/lib/kernel/ebin/user.beam
index ed5f753bf2..b9cf728e93 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 9ee84fbe9f..3feffb9332 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/ebin/user_sup.beam b/bootstrap/lib/kernel/ebin/user_sup.beam
index dfd2cdc2b5..5632210843 100644
--- a/bootstrap/lib/kernel/ebin/user_sup.beam
+++ b/bootstrap/lib/kernel/ebin/user_sup.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/wrap_log_reader.beam b/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
index c6c230f689..cdb87c3fd5 100644
--- a/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
+++ b/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/array.beam b/bootstrap/lib/stdlib/ebin/array.beam
index 1c42860910..a3049ae953 100644
--- a/bootstrap/lib/stdlib/ebin/array.beam
+++ b/bootstrap/lib/stdlib/ebin/array.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/base64.beam b/bootstrap/lib/stdlib/ebin/base64.beam
index 4f05f8923a..101ffc3904 100644
--- a/bootstrap/lib/stdlib/ebin/base64.beam
+++ b/bootstrap/lib/stdlib/ebin/base64.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/beam_lib.beam b/bootstrap/lib/stdlib/ebin/beam_lib.beam
index 8ad4dbb149..58123d66be 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 bc43ffd9de..e5fe08f44f 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/calendar.beam b/bootstrap/lib/stdlib/ebin/calendar.beam
index 4e7558cda0..715eed8dd9 100644
--- a/bootstrap/lib/stdlib/ebin/calendar.beam
+++ b/bootstrap/lib/stdlib/ebin/calendar.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam
index d8dc4376b0..8b637ab064 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_server.beam b/bootstrap/lib/stdlib/ebin/dets_server.beam
index ef990f42e4..5978a933ed 100644
--- a/bootstrap/lib/stdlib/ebin/dets_server.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_server.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_sup.beam b/bootstrap/lib/stdlib/ebin/dets_sup.beam
index 9a2ee668fd..9bc79d6468 100644
--- a/bootstrap/lib/stdlib/ebin/dets_sup.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_sup.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam
index 4dfbe15f08..36d38c4e9a 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_v8.beam b/bootstrap/lib/stdlib/ebin/dets_v8.beam
index 9eac024246..81d51ea402 100644
--- a/bootstrap/lib/stdlib/ebin/dets_v8.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_v8.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_v9.beam b/bootstrap/lib/stdlib/ebin/dets_v9.beam
index 1515b306b3..2a247effc1 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/dict.beam b/bootstrap/lib/stdlib/ebin/dict.beam
index 9739e189da..3d0b4194b6 100644
--- a/bootstrap/lib/stdlib/ebin/dict.beam
+++ b/bootstrap/lib/stdlib/ebin/dict.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph.beam b/bootstrap/lib/stdlib/ebin/digraph.beam
index bc87cabcd6..41043bf729 100644
--- a/bootstrap/lib/stdlib/ebin/digraph.beam
+++ b/bootstrap/lib/stdlib/ebin/digraph.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/digraph_utils.beam b/bootstrap/lib/stdlib/ebin/digraph_utils.beam
index 7f51b3946f..e0c15a218a 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 a165100727..7a2b065674 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/edlin_expand.beam b/bootstrap/lib/stdlib/ebin/edlin_expand.beam
index bd0bfbec34..1719b3bb45 100644
--- a/bootstrap/lib/stdlib/ebin/edlin_expand.beam
+++ b/bootstrap/lib/stdlib/ebin/edlin_expand.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index 0433b937ea..4d072403ec 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_bits.beam b/bootstrap/lib/stdlib/ebin/erl_bits.beam
index 2270dbeae8..7b1f8bb764 100644
--- a/bootstrap/lib/stdlib/ebin/erl_bits.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_bits.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_compile.beam b/bootstrap/lib/stdlib/ebin/erl_compile.beam
index 761351eee6..cc4ef260d0 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_eval.beam b/bootstrap/lib/stdlib/ebin/erl_eval.beam
index f12c413f72..dfd10fb4bf 100644
--- a/bootstrap/lib/stdlib/ebin/erl_eval.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_eval.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
index b3486744eb..00eabdb116 100644
--- a/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_expand_records.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_internal.beam b/bootstrap/lib/stdlib/ebin/erl_internal.beam
index 3eb1cb913e..1609ae4997 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 138d03d2fe..08da4563a7 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 a6ab35f0eb..2c0ce68987 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_posix_msg.beam b/bootstrap/lib/stdlib/ebin/erl_posix_msg.beam
index ae8abf77a2..696c854e8a 100644
--- a/bootstrap/lib/stdlib/ebin/erl_posix_msg.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_posix_msg.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_pp.beam b/bootstrap/lib/stdlib/ebin/erl_pp.beam
index b11a329c5c..0d15bb2300 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 77c84d3667..73f9a4ac97 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 0a8f2bac4d..40d41d0202 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/error_logger_file_h.beam b/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam
index fc890a8408..ae5a7020ea 100644
--- a/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam
+++ b/bootstrap/lib/stdlib/ebin/error_logger_file_h.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam b/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam
index a6046b084e..6065cfa8f1 100644
--- a/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam
+++ b/bootstrap/lib/stdlib/ebin/error_logger_tty_h.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/escript.beam b/bootstrap/lib/stdlib/ebin/escript.beam
index b904155ca8..20e6a25f1d 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 b0c07bafdc..17ea23e03b 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/eval_bits.beam b/bootstrap/lib/stdlib/ebin/eval_bits.beam
index 0feff1b3f4..de2d528f2e 100644
--- a/bootstrap/lib/stdlib/ebin/eval_bits.beam
+++ b/bootstrap/lib/stdlib/ebin/eval_bits.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/file_sorter.beam b/bootstrap/lib/stdlib/ebin/file_sorter.beam
index 20bf8a5921..c8655b18b5 100644
--- a/bootstrap/lib/stdlib/ebin/file_sorter.beam
+++ b/bootstrap/lib/stdlib/ebin/file_sorter.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filelib.beam b/bootstrap/lib/stdlib/ebin/filelib.beam
index 158453948e..f3065882ae 100644
--- a/bootstrap/lib/stdlib/ebin/filelib.beam
+++ b/bootstrap/lib/stdlib/ebin/filelib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam
index c20e4aedff..f419480f6e 100644
--- a/bootstrap/lib/stdlib/ebin/filename.beam
+++ b/bootstrap/lib/stdlib/ebin/filename.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gb_sets.beam b/bootstrap/lib/stdlib/ebin/gb_sets.beam
index f013fcde9f..1ce3e0bd83 100644
--- a/bootstrap/lib/stdlib/ebin/gb_sets.beam
+++ b/bootstrap/lib/stdlib/ebin/gb_sets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gb_trees.beam b/bootstrap/lib/stdlib/ebin/gb_trees.beam
index 313dc31dee..c462bee0c1 100644
--- a/bootstrap/lib/stdlib/ebin/gb_trees.beam
+++ b/bootstrap/lib/stdlib/ebin/gb_trees.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen.beam b/bootstrap/lib/stdlib/ebin/gen.beam
index 18f9223677..bf09b84de6 100644
--- a/bootstrap/lib/stdlib/ebin/gen.beam
+++ b/bootstrap/lib/stdlib/ebin/gen.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/gen_event.beam b/bootstrap/lib/stdlib/ebin/gen_event.beam
index 44e9df9937..662d4af25c 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 74557db735..d5d027ce1e 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 cf51f0d7d4..5c2c569016 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.beam b/bootstrap/lib/stdlib/ebin/io.beam
index 3ae720922d..a9f24817b3 100644
--- a/bootstrap/lib/stdlib/ebin/io.beam
+++ b/bootstrap/lib/stdlib/ebin/io.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib.beam b/bootstrap/lib/stdlib/ebin/io_lib.beam
index fa9645e487..984f0f6116 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_format.beam b/bootstrap/lib/stdlib/ebin/io_lib_format.beam
index 36afe01b19..16907bb3aa 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_format.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_format.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_fread.beam b/bootstrap/lib/stdlib/ebin/io_lib_fread.beam
index c35bb2456c..bebe0a6c75 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_fread.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_fread.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 8f301d8e9a..6b8b7a3267 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 58a789f963..d7e591ed35 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 d07fe99605..ef6dcfb6ea 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/log_mf_h.beam b/bootstrap/lib/stdlib/ebin/log_mf_h.beam
index 104665d8c4..70b887857c 100644
--- a/bootstrap/lib/stdlib/ebin/log_mf_h.beam
+++ b/bootstrap/lib/stdlib/ebin/log_mf_h.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/math.beam b/bootstrap/lib/stdlib/ebin/math.beam
index 2ccba3a266..0103016730 100644
--- a/bootstrap/lib/stdlib/ebin/math.beam
+++ b/bootstrap/lib/stdlib/ebin/math.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam
index f3717a2910..0dc991553b 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/orddict.beam b/bootstrap/lib/stdlib/ebin/orddict.beam
index 50ae0da7c6..0f3850677f 100644
--- a/bootstrap/lib/stdlib/ebin/orddict.beam
+++ b/bootstrap/lib/stdlib/ebin/orddict.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ordsets.beam b/bootstrap/lib/stdlib/ebin/ordsets.beam
index 0fa7538664..c3f2c3b7b1 100644
--- a/bootstrap/lib/stdlib/ebin/ordsets.beam
+++ b/bootstrap/lib/stdlib/ebin/ordsets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam
index 15225ca165..f9256f3f4c 100644
--- a/bootstrap/lib/stdlib/ebin/otp_internal.beam
+++ b/bootstrap/lib/stdlib/ebin/otp_internal.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/pg.beam b/bootstrap/lib/stdlib/ebin/pg.beam
index 68dbb99b3a..aadf03ca28 100644
--- a/bootstrap/lib/stdlib/ebin/pg.beam
+++ b/bootstrap/lib/stdlib/ebin/pg.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/pool.beam b/bootstrap/lib/stdlib/ebin/pool.beam
index ad90bfb403..35c2da9051 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 121e1b3c99..c366aafadf 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/proplists.beam b/bootstrap/lib/stdlib/ebin/proplists.beam
index 37f270e17d..378392c791 100644
--- a/bootstrap/lib/stdlib/ebin/proplists.beam
+++ b/bootstrap/lib/stdlib/ebin/proplists.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam
index 627cb5bafb..a9260708e5 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 3595e6c4bf..7fb399a66b 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 f9eaf4d071..19d24cfaa6 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/random.beam b/bootstrap/lib/stdlib/ebin/random.beam
index 70418d4f35..9f2361d586 100644
--- a/bootstrap/lib/stdlib/ebin/random.beam
+++ b/bootstrap/lib/stdlib/ebin/random.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/re.beam b/bootstrap/lib/stdlib/ebin/re.beam
index b9b2c13e39..ae7bf3a734 100644
--- a/bootstrap/lib/stdlib/ebin/re.beam
+++ b/bootstrap/lib/stdlib/ebin/re.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/regexp.beam b/bootstrap/lib/stdlib/ebin/regexp.beam
index 41bb67e2b6..f45899702c 100644
--- a/bootstrap/lib/stdlib/ebin/regexp.beam
+++ b/bootstrap/lib/stdlib/ebin/regexp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sets.beam b/bootstrap/lib/stdlib/ebin/sets.beam
index f304c5f02d..b8ce3ebe89 100644
--- a/bootstrap/lib/stdlib/ebin/sets.beam
+++ b/bootstrap/lib/stdlib/ebin/sets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam
index b05bf875e3..fc3552621d 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/shell_default.beam b/bootstrap/lib/stdlib/ebin/shell_default.beam
index f41802634f..aa600600d0 100644
--- a/bootstrap/lib/stdlib/ebin/shell_default.beam
+++ b/bootstrap/lib/stdlib/ebin/shell_default.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/slave.beam b/bootstrap/lib/stdlib/ebin/slave.beam
index cf0268051a..cf030178ef 100644
--- a/bootstrap/lib/stdlib/ebin/slave.beam
+++ b/bootstrap/lib/stdlib/ebin/slave.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index e87eee5c3b..a67389fdf4 100644
--- a/bootstrap/lib/stdlib/ebin/sofs.beam
+++ b/bootstrap/lib/stdlib/ebin/sofs.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.app b/bootstrap/lib/stdlib/ebin/stdlib.app
index 02286dada6..ff81f58bcc 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -19,7 +19,7 @@
%%
{application, stdlib,
[{description, "ERTS CXC 138 10"},
- {vsn, "1.16.4"},
+ {vsn, "1.16.5"},
{modules, [array,
base64,
beam_lib,
diff --git a/bootstrap/lib/stdlib/ebin/stdlib.appup b/bootstrap/lib/stdlib/ebin/stdlib.appup
index 3e346f25a6..a52ce1a4f0 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.appup
+++ b/bootstrap/lib/stdlib/ebin/stdlib.appup
@@ -1 +1 @@
-{"1.16.4",[],[]}.
+{"1.16.5",[],[]}.
diff --git a/bootstrap/lib/stdlib/ebin/string.beam b/bootstrap/lib/stdlib/ebin/string.beam
index 9e87b05313..3c3eaf6ed2 100644
--- a/bootstrap/lib/stdlib/ebin/string.beam
+++ b/bootstrap/lib/stdlib/ebin/string.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam
index 18b14a2b97..3f4952a42f 100644
--- a/bootstrap/lib/stdlib/ebin/supervisor.beam
+++ b/bootstrap/lib/stdlib/ebin/supervisor.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam
index ac9bffe1ba..3880293d47 100644
--- a/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam
+++ b/bootstrap/lib/stdlib/ebin/supervisor_bridge.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sys.beam b/bootstrap/lib/stdlib/ebin/sys.beam
index 14144c14e3..5a75152833 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/timer.beam b/bootstrap/lib/stdlib/ebin/timer.beam
index d4aa4f928c..9d9d42f96d 100644
--- a/bootstrap/lib/stdlib/ebin/timer.beam
+++ b/bootstrap/lib/stdlib/ebin/timer.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/unicode.beam b/bootstrap/lib/stdlib/ebin/unicode.beam
index 78d140ee2b..66d6991283 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/win32reg.beam b/bootstrap/lib/stdlib/ebin/win32reg.beam
index 30bdf10bd8..45b268ebac 100644
--- a/bootstrap/lib/stdlib/ebin/win32reg.beam
+++ b/bootstrap/lib/stdlib/ebin/win32reg.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/zip.beam b/bootstrap/lib/stdlib/ebin/zip.beam
index 33fa118852..63a03efaf0 100644
--- a/bootstrap/lib/stdlib/ebin/zip.beam
+++ b/bootstrap/lib/stdlib/ebin/zip.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/egen/erl_parse.erl b/bootstrap/lib/stdlib/egen/erl_parse.erl
index 754e943beb..684f65386f 100644
--- a/bootstrap/lib/stdlib/egen/erl_parse.erl
+++ b/bootstrap/lib/stdlib/egen/erl_parse.erl
@@ -529,7 +529,7 @@ get_attribute(L, Name) ->
get_attributes(L) ->
erl_scan:attributes_info(L).
--file("/usr/local/otp/releases/otp_beam_linux_sles10_i386_r13b02_patched/lib/parsetools-2.0/include/yeccpre.hrl", 0).
+-file("/usr/local/otp/releases/sles10_32_R13B03_patched/lib/parsetools-2.0.1/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
diff --git a/erts/.gitignore b/erts/.gitignore
new file mode 100644
index 0000000000..526d5da0b9
--- /dev/null
+++ b/erts/.gitignore
@@ -0,0 +1,22 @@
+/Makefile
+/configure
+/config.log
+/config.status
+/config.h.in
+
+/start_scripts/RELEASES.src
+/start_scripts/*.rel
+/start_scripts/*.boot
+/start_scripts/*.script
+
+/etc/common/Install
+/etc/common/erl.src
+
+/test/Emakefile
+/test/*.beam
+
+/emulator/test/Emakefile
+/emulator/test/*.beam
+/emulator/test/*_no_opt_SUITE.erl
+
+/emulator/pcre/pcre_exec_loop_break_cases.inc
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 0ad963db12..e9a0cc228f 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1,4 +1,4 @@
-
+dnl
dnl %CopyrightBegin%
dnl
dnl Copyright Ericsson AB 1998-2009. All Rights Reserved.
@@ -15,6 +15,7 @@ dnl the License for the specific language governing rights and limitations
dnl under the License.
dnl
dnl %CopyrightEnd%
+dnl
dnl
dnl aclocal.m4
@@ -519,46 +520,79 @@ dnl On ofs1 the '-pthread' switch should be used
ETHR_DEFS="$ETHR_DEFS -D_POSIX_PTHREAD_SEMANTICS" ;;
linux*)
ETHR_DEFS="$ETHR_DEFS -D_POSIX_THREAD_SAFE_FUNCTIONS -D_GNU_SOURCE"
- if test "x$erl_xcomp_linux_kernel" != "x"; then
- linux_kernel_vsn_=$erl_xcomp_linux_kernel
- else
- linux_kernel_vsn_=`uname -r`
- fi
- usable_sigusrx=no
- usable_sigaltstack=no
- # FIXME: Test for actual problems instead of kernel versions.
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-1]]|2.[[0-1]].*)
- ;;
- 2.[[2-3]]|2.[[2-3]].*)
- usable_sigusrx=yes
- ;;
- *)
+ if test X$cross_compiling = Xyes; then
+ if test "X$erl_xcomp_linux_usable_sigusrx" = "X"; then
usable_sigusrx=yes
+ usable_sigusrx_guessed=yes
+ else
+ usable_sigusrx=$erl_xcomp_linux_usable_sigusrx
+ usable_sigusrx_guessed=no
+ fi
+ if test "X$erl_xcomp_linux_usable_sigaltstack" = "X"; then
usable_sigaltstack=yes
- ;;
- esac
+ usable_sigaltstack_guessed=yes
+ else
+ usable_sigaltstack=$erl_xcomp_linux_usable_sigaltstack
+ usable_sigaltstack_guessed=no
+ fi
+ else
+ # FIXME: Test for actual problems instead of kernel versions
+ linux_kernel_vsn_=`uname -r`
+ case $linux_kernel_vsn_ in
+ [[0-1]].*|2.[[0-1]]|2.[[0-1]].*)
+ usable_sigusrx=no
+ usable_sigaltstack=no;;
+ 2.[[2-3]]|2.[[2-3]].*)
+ usable_sigusrx=yes
+ usable_sigaltstack=no;;
+ *)
+ usable_sigusrx=yes
+ usable_sigaltstack=yes;;
+ esac
+ usable_sigusrx_guessed=no
+ usable_sigaltstack_guessed=no
+ fi
AC_MSG_CHECKING(if SIGUSR1 and SIGUSR2 can be used)
AC_MSG_RESULT($usable_sigusrx)
+ if test $usable_sigusrx_guessed = yes; then
+ AC_MSG_WARN([result $usable_sigusrx guessed because of cross compilation])
+ fi
if test $usable_sigusrx = no; then
ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGUSRX"
fi
AC_MSG_CHECKING(if sigaltstack can be used)
AC_MSG_RESULT($usable_sigaltstack)
+ if test $usable_sigaltstack_guessed = yes; then
+ AC_MSG_WARN([result $usable_sigaltstack guessed because of cross compilation])
+ fi
if test $usable_sigaltstack = no; then
ETHR_DEFS="$ETHR_DEFS -DETHR_UNUSABLE_SIGALTSTACK"
fi
AC_MSG_CHECKING(for Native POSIX Thread Library)
- case `getconf GNU_LIBPTHREAD_VERSION 2>/dev/null` in
- nptl*) nptl=yes;;
- NPTL*) nptl=yes;;
- *) nptl=no;;
- esac
+ if test X$cross_compiling = Xyes; then
+ if test "X$erl_xcomp_linux_nptl" = "X"; then
+ nptl=yes
+ nptl_guessed=yes
+ else
+ nptl=$erl_xcomp_linux_nptl
+ nptl_guessed=no
+ fi
+ else
+ case `getconf GNU_LIBPTHREAD_VERSION 2>/dev/null` in
+ nptl*) nptl=yes;;
+ NPTL*) nptl=yes;;
+ *) nptl=no;;
+ esac
+ nptl_guessed=no
+ fi
AC_MSG_RESULT($nptl)
+ if test $nptl_guessed = yes; then
+ AC_MSG_WARN([result $nptl guessed because of cross compilation])
+ fi
if test $nptl = yes; then
ETHR_THR_LIB_BASE_NAME=nptl
fi
@@ -567,7 +601,10 @@ dnl On ofs1 the '-pthread' switch should be used
AC_CHECK_HEADER(nptl/pthread.h, need_nptl_incldir=yes)
if test $need_nptl_incldir = yes; then
# Ahh...
- nptl_path="$C_INCLUDE_PATH:$CPATH:/usr/local/include:/usr/include"
+ nptl_path="$C_INCLUDE_PATH:$CPATH"
+ if test X$cross_compiling != Xyes; then
+ nptl_path="$nptl_path:/usr/local/include:/usr/include"
+ fi
nptl_ws_path=
save_ifs="$IFS"; IFS=":"
for dir in $nptl_path; do
@@ -683,7 +720,7 @@ if test "x$ETHR_THR_LIB_BASE" != "x"; then
ETHR_LIB_NAME=$ethr_lib_name
fi
-AC_CHECK_SIZEOF(void *, 4)
+AC_CHECK_SIZEOF(void *)
AC_DEFINE_UNQUOTED(ETHR_SIZEOF_PTR, $ac_cv_sizeof_void_p, [Define to the size of pointers])
if test "X$disable_native_ethr_impls" = "Xyes"; then
@@ -751,13 +788,21 @@ case $clock_gettime_correction in
case $clock_gettime_correction in
unknown)
if test x$clock_gettime_compiles = xyes; then
- linux_kernel_vsn_=`uname -r`
- case $linux_kernel_vsn_ in
- [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
- erl_cv_time_correction=times ;;
- *)
- erl_cv_time_correction=clock_gettime;;
- esac
+ if test X$cross_compiling != Xyes; then
+ if test "X$erl_xcomp_linux_clock_gettime_correction" = "Xno"; then
+ erl_cv_time_correction=times
+ else
+ erl_cv_time_correction=clock_gettime
+ fi
+ else
+ linux_kernel_vsn_=`uname -r`
+ case $linux_kernel_vsn_ in
+ [[0-1]].*|2.[[0-5]]|2.[[0-5]].*)
+ erl_cv_time_correction=times ;;
+ *)
+ erl_cv_time_correction=clock_gettime;;
+ esac
+ fi
else
erl_cv_time_correction=times
fi
@@ -774,6 +819,7 @@ case $clock_gettime_correction in
;;
esac
])
+
xrtlib=""
case $erl_cv_time_correction in
times)
@@ -781,6 +827,9 @@ case $erl_cv_time_correction in
[Define if you do not have a high-res. timer & want to use times() instead])
;;
clock_gettime)
+ if test X$cross_compiling = Xyes -a X$erl_xcomp_linux_clock_gettime_correction = X; then
+ AC_MSG_WARN([result clock_gettime guessed because of cross compilation])
+ fi
xrtlib="-lrt"
AC_DEFINE(GETHRTIME_WITH_CLOCK_GETTIME,[1],
[Define if you want to use clock_gettime to simulate gethrtime])
@@ -840,7 +889,15 @@ int main() {
exit(5);
exit(0); return 0;
}
-], erl_gethrvtime=procfs_ioctl, erl_gethrvtime=false, erl_gethrvtime=false)
+],
+erl_gethrvtime=procfs_ioctl,
+erl_gethrvtime=false,
+if test "x$erl_xcomp_gethrvtime_procfs_ioctl" = "xyes"; then
+ erl_gethrvtime=procfs_ioctl
+else
+ erl_gethrvtime=false
+fi)
+
case $erl_gethrvtime in
procfs_ioctl)
AC_DEFINE(HAVE_GETHRVTIME_PROCFS_IOCTL,[1],
@@ -880,7 +937,14 @@ case $erl_gethrvtime in
exit(5);
exit(0); return 0;
}
- ], erl_clock_gettime=true, erl_clock_gettime=false, erl_clock_gettime=false)
+ ],
+ erl_clock_gettime=true,
+ erl_clock_gettime=false,
+ if test "x$erl_xcomp_clock_gettime" = "xyes"; then
+ erl_clock_gettime=true
+ else
+ erl_clock_gettime=false
+ fi)
LIBS=$save_libs
case $host_os in
linux*)
diff --git a/erts/configure.in b/erts/configure.in
index 370646930f..ea97d73aa8 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1,20 +1,20 @@
dnl Process this file with autoconf to produce a configure script. -*-m4-*-
dnl %CopyrightBegin%
-dnl
-dnl Copyright Ericsson AB 1997-2009. All Rights Reserved.
-dnl
+dnl
+dnl Copyright Ericsson AB 1997-2010. All Rights Reserved.
+dnl
dnl The contents of this file are subject to the Erlang Public License,
dnl Version 1.1, (the "License"); you may not use this file except in
dnl compliance with the License. You should have received a copy of the
dnl Erlang Public License along with this software. If not, it can be
dnl retrieved online at http://www.erlang.org/.
-dnl
+dnl
dnl Software distributed under the License is distributed on an "AS IS"
dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
dnl the License for the specific language governing rights and limitations
dnl under the License.
-dnl
+dnl
dnl %CopyrightEnd%
dnl The string "FIXME convbreak" means that there is a break of
@@ -94,13 +94,6 @@ enable_child_waiter_thread=no
ENABLE_ALLOC_TYPE_VARS=
AC_SUBST(ENABLE_ALLOC_TYPE_VARS)
-AC_ARG_WITH(xcomp-conf,
-[ --with-xcompconf=PATH path to cross compilation configuration])
-if test "x$with_xcompconf" != "xno" -a "x$with_xcompconf" != "x" ; then
- . $with_xcompconf
-fi
-
-
AC_ARG_ENABLE(threads,
[ --enable-threads enable async thread support
--disable-threads disable async thread support],
@@ -467,22 +460,18 @@ AC_SUBST(DEBUG_CFLAGS)
AC_SUBST(WFLAGS)
AC_SUBST(CFLAG_RUNTIME_LIBRARY_PATH)
-AC_CHECK_SIZEOF(void *, $erl_xcomp_void_p) # Needed for ARCH and smp checks below
+AC_CHECK_SIZEOF(void *) # Needed for ARCH and smp checks below
dnl
dnl Figure out operating system and cpu architecture
dnl
-if test "x$erl_xcomp_os" != "x"; then
- chk_opsys_=$erl_xcomp_os
+if test "x$host_alias" != "x"; then
+ chk_opsys_=$host_os
else
- if test "x$host_os" = "xwin32"; then
- chk_opsys_=win32
- else
- chk_opsys_=`uname -s`
- if test "x$chk_opsys_" = "xSunOS"; then
- chk_opsys_=$chk_opsys_`uname -r`
- fi
+ chk_opsys_=`uname -s`
+ if test "x$chk_opsys_" = "xSunOS"; then
+ chk_opsys_=$chk_opsys_`uname -r`
fi
fi
case $chk_opsys_ in
@@ -494,11 +483,12 @@ case $chk_opsys_ in
*) OPSYS=noopsys
esac
-if test "x$erl_xcomp_hw" != "x"; then
- chk_arch_=$erl_xcomp_hw
+if test "x$host_alias" != "x" -a "x$host_cpu" != "x"; then
+ chk_arch_=$host_cpu
else
chk_arch_=`uname -m`
fi
+
case $chk_arch_ in
sun4u) ARCH=ultrasparc;;
sparc64) ARCH=sparc64;;
@@ -1299,11 +1289,11 @@ dnl Interactive UX needs <net/errno.h> for socket related error codes.
dnl Some Linuxes needs <sys/socketio.h> instead of <sys/sockio.h>
dnl
AC_CHECK_HEADERS(fcntl.h limits.h unistd.h syslog.h dlfcn.h ieeefp.h \
- sys/stropts.h sys/sysctl.h \
+ sys/types.h sys/stropts.h sys/sysctl.h \
sys/ioctl.h sys/time.h sys/uio.h \
sys/socket.h sys/sockio.h sys/socketio.h \
net/errno.h malloc.h mach-o/dyld.h arpa/nameser.h \
- pty.h util.h utmp.h langinfo.h)
+ pty.h util.h utmp.h langinfo.h poll.h)
AC_CHECK_HEADER(sys/resource.h,
[AC_DEFINE(HAVE_SYS_RESOURCE_H, 1,
@@ -1392,11 +1382,13 @@ LM_STRUCT_SOCKADDR_SA_LEN
LM_STRUCT_EXCEPTION
AC_CHECK_SIZEOF(char, 1)
-AC_CHECK_SIZEOF(short, $erl_xcomp_short)
-AC_CHECK_SIZEOF(int, $erl_xcomp_int)
-AC_CHECK_SIZEOF(long, $erl_xcomp_long)
-AC_CHECK_SIZEOF(void *, $erl_xcomp_void_p)
-AC_CHECK_SIZEOF(long long, $erl_xcomp_long_long)
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(long long)
+AC_CHECK_SIZEOF(size_t)
+AC_CHECK_SIZEOF(off_t)
BITS64=
@@ -1460,71 +1452,26 @@ int main(void)
abort ();
return 0;
}
-],AC_MSG_RESULT(no)
-,AC_MSG_RESULT(yes)
-AC_MSG_ERROR([This gcc miscompiles the Erlang runtime system; please use a different version])
-,AC_MSG_RESULT(no))
-fi
-
-dnl AC_CHECK_SIZEOF(size_t, 4)dnl Assumes all cross compiling is to 32bit uP
-dnl
-dnl The disabled one above does not include stddef.h, alas!
-dnl
-AC_CACHE_CHECK([size of size_t], ac_cv_sizeof_size_t,
-AC_TRY_RUN([
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-int main(int argc, char **argv) {
- FILE *f = fopen("conftestval", "w");
- if (! f)
- exit(1); /* Failed */
- fprintf(f, "%d\n", (int) sizeof(size_t));
- exit(0); /* OK */
-}
-], ac_cv_sizeof_size_t=`cat conftestval`
-, ac_cv_sizeof_size_t=0
-, ac_cv_sizeof_size_t=$erl_xcomp_sizeof_size_t))
-AC_DEFINE_UNQUOTED(SIZEOF_SIZE_T, $ac_cv_sizeof_size_t, [The number of bytes in a size_t])
+], gcc_4_3_0_bug=no, gcc_4_3_0_bug=yes, gcc_4_3_0_bug=cross)
+
+case $gcc_4_3_0_bug in
+ yes|no)
+ gcc_4_3_0_bug_result=$gcc_4_3_0_bug;;
+ cross)
+ gcc_dumped_vsn=`$CC -dumpversion 2>/dev/null`
+ case gcc-$gcc_dumped_vsn in
+ gcc-4.3.0) gcc_4_3_0_bug=yes;;
+ *) gcc_4_3_0_bug=no;;
+ esac
+ gcc_4_3_0_bug_result="$gcc_4_3_0_bug; could not run test since cross compiling, checked version number ($gcc_dumped_vsn) instead";;
+esac
-dnl A standard size check does not include sys/types.h
-dnl
-AC_CACHE_CHECK([size of off_t], ac_cv_sizeof_off_t,
-AC_TRY_RUN([
-#include <sys/types.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-int main(int argc, char **argv) {
- FILE *f = fopen("conftestval", "w");
- if (! f)
- exit(1); /* Failed */
- fprintf(f, "%d\n", (int) sizeof(off_t));
- exit(0); /* OK */
-}
-], ac_cv_sizeof_off_t=`cat conftestval`
-, ac_cv_sizeof_off_t=0
-, ac_cv_sizeof_off_t=$erl_xcomp_sizeof_off_t))
-AC_DEFINE_UNQUOTED(SIZEOF_OFF_T, $ac_cv_sizeof_off_t,
- [The number of bytes in an off_t])
+AC_MSG_RESULT([$gcc_4_3_0_bug_result])
+if test $gcc_4_3_0_bug = yes; then
+ AC_MSG_ERROR([This gcc miscompiles the Erlang runtime system; please use a different version])
+fi
-AC_MSG_CHECKING([int/long/void*/size_t sizes])
-AC_TRY_RUN([
-#include <stdlib.h>
-#include <stddef.h>
-int main(int argc, char **argv) {
- if (sizeof(void *) >= 4 &&
- sizeof(void *) == sizeof(size_t) &&
- (sizeof(void *) == sizeof(int) || sizeof(void *) == sizeof(long))) {
- exit(0); /* OK */
- }
- exit(1); /* Failed */
-}
-],AC_MSG_RESULT(ok)
-,AC_MSG_RESULT(failed)
-AC_MSG_ERROR([Cannot handle this combination of int/long/void*/size_t sizes])
-,AC_MSG_RESULT(ok))
+fi
if test "x$erl_xcomp_bigendian" != "x"; then
ac_cv_c_bigendian=$erl_xcomp_bigendian
@@ -1585,7 +1532,7 @@ AC_CHECK_FUNCS([ieee_handler fpsetmask finite isnan isinf res_gethostbyname dlop
pread pwrite writev memmove strerror strerror_r strncasecmp \
gethrtime localtime_r gmtime_r mremap memcpy mallopt \
sbrk _sbrk __sbrk brk _brk __brk \
- flockfile fstat strlcpy strlcat setsid posix2time setlocale nl_langinfo])
+ flockfile fstat strlcpy strlcat setsid posix2time setlocale nl_langinfo poll])
if test "X$host" = "Xwin32"; then
ac_cv_func_setvbuf_reversed=yes
fi
@@ -1861,9 +1808,11 @@ int main(void)
erts_cv___after_morecore_hook_can_track_malloc=no,
if test "x$erl_xcomp_after_morecore_hook" != "x"; then
erts_cv___after_morecore_hook_can_track_malloc=$erl_xcomp_after_morecore_hook
+ else
+ erts_cv___after_morecore_hook_can_track_malloc=no
fi)])
-if test "x$erts_cv___after_morecore_hook_can_track_malloc" = "xyes"; then
+if test $erts_cv___after_morecore_hook_can_track_malloc = yes; then
AC_DEFINE(ERTS___AFTER_MORECORE_HOOK_CAN_TRACK_MALLOC, 1, \
[Define if __after_morecore_hook can track malloc()s core memory use.])
fi
@@ -2119,7 +2068,11 @@ int main(void)
],
erts_cv_brk_wrappers_can_track_malloc=yes,
erts_cv_brk_wrappers_can_track_malloc=no,
- erts_cv_brk_wrappers_can_track_malloc=no)])
+ if test "x$erl_xcomp_dlsym_brk_wrappers" != "x"; then
+ erts_cv_brk_wrappers_can_track_malloc=$erl_xcomp_dlsym_brk_wrappers
+ else
+ erts_cv_brk_wrappers_can_track_malloc=no
+ fi)])
if test $erts_cv_brk_wrappers_can_track_malloc = yes; then
AC_DEFINE(ERTS_BRK_WRAPPERS_CAN_TRACK_MALLOC, 1, \
[Define if sbrk()/brk() wrappers can track malloc()s core memory use])
@@ -2702,7 +2655,14 @@ int main(int argc, const char **argv)
do_fmul();
return do_check();
}
-], erl_ok=reliable, erl_ok=unreliable, erl_ok=unreliable)
+],
+erl_ok=reliable,
+erl_ok=unreliable,
+if test "x$erl_xcomp_reliable_fpe" = "xyes"; then
+ erl_ok=reliable
+else
+ erl_ok=unreliable
+fi)
if test $erl_ok = unreliable; then
AC_DEFINE(NO_FPE_SIGNALS,[],
[Define if floating points exceptions are non-existing/not reliable])
@@ -2848,9 +2808,12 @@ fi
# Check for working poll().
#
AC_MSG_CHECKING([for working poll()])
-if test "x$erl_xcomp_poll" != "x"; then
- poll_works=$erl_xcomp_poll
+if test "x$ac_cv_header_poll_h" != "xyes" -o "x$ac_cv_func_poll" != "xyes"; then
+
+poll_works=no
+
else
+
AC_TRY_RUN([
#include <poll.h>
main()
@@ -2870,23 +2833,43 @@ main()
exit(0);
#endif
}
-], poll_works=true, poll_works=false, poll_works=false)
+],
+poll_works=yes,
+poll_works=no,
+poll_works=$erl_xcomp_poll)
+
+if test "X$poll_works" != "X"; then
+ guessed_poll_works=no
+else
+ guessed_poll_works=yes
+ case $host_os in
+ darwin*) poll_works=no;;
+ *) poll_works=yes;;
+ esac
+fi
+
fi
+
case $poll_works in
-true)
+yes)
AC_DEFINE(ERTS_USE_POLL, 1, [Define if poll() should be used instead of select()])
- AC_MSG_RESULT(ok)
+ AC_MSG_RESULT(yes)
;;
*)
#
# The USE_SELECT define is used by the ssl application (should not
# be used by erts).
#
+ poll_works=no
AC_DEFINE(USE_SELECT, 1, [Define if select() should be used instead of poll()])
- AC_MSG_RESULT(broken or based on select())
+ AC_MSG_RESULT([no; non-existing, broken, or based on select()])
;;
esac
+if test $guessed_poll_works = yes; then
+ AC_MSG_WARN([result $poll_works guessed based on OS ($host_os) because of cross compilation])
+fi
+
#
# If kqueue() found, check that it can be selected or polled on...
#
@@ -2922,7 +2905,14 @@ int main(void) {
}
return 0;
}
- ], ok_kqueue=true, ok_kqueue=false, ok_kqueue=false)
+ ],
+ ok_kqueue=true,
+ ok_kqueue=false,
+ if test "x$erl_xcomp_kqueue" = "xyes"; then
+ ok_kqueue=true
+ else
+ ok_kqueue=false
+ fi)
if test $ok_kqueue = true; then
AC_MSG_RESULT(yes);
else
@@ -3012,7 +3002,15 @@ int main(void) {
return 5;
return 0;
}
-], copying_putenv=yes, copying_putenv=no, copying_putenv=no)
+],
+copying_putenv=yes,
+copying_putenv=no,
+if test "x$erl_xcomp_putenv_copy" != "x"; then
+ copying_putenv=$erl_xcomp_putenv_copy
+else
+ copying_putenv=no
+fi)
+
if test $copying_putenv = yes; then
AC_DEFINE(HAVE_COPYING_PUTENV,[1],[Define if you have a putenv() that stores a copy of the key-value pair])
fi
diff --git a/erts/doc/src/erl_dist_protocol.xml b/erts/doc/src/erl_dist_protocol.xml
index 9a203289e9..5978af178a 100644
--- a/erts/doc/src/erl_dist_protocol.xml
+++ b/erts/doc/src/erl_dist_protocol.xml
@@ -129,8 +129,8 @@ By default EPMD listens on port 4369.
<cell align="center">PortNo</cell>
<cell align="center">NodeType</cell>
<cell align="center">Protocol</cell>
- <cell align="center">LowestVersion</cell>
<cell align="center">HighestVersion</cell>
+ <cell align="center">LowestVersion</cell>
<cell align="center">Nlen</cell>
<cell align="center">NodeName</cell>
<cell align="center">Elen</cell>
@@ -150,16 +150,16 @@ By default EPMD listens on port 4369.
<item>
0 = tcp/ip-v4, ...
</item>
- <tag><c>LowestVersion</c></tag>
- <item>
- The lowest distribution version that this node can handle.
- See the next field for possible values.
- </item>
<tag><c>HighestVersion</c></tag>
<item>
The highest distribution version that this node can handle.
The value in R6B and later is 5.
</item>
+ <tag><c>LowestVersion</c></tag>
+ <item>
+ The lowest distribution version that this node can handle.
+ The value in R6B and later is 5.
+ </item>
<tag><c>Nlen</c></tag>
<item>
The length of the <c>NodeName</c>.
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index c636d65ef3..2033ba8a66 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -34,12 +34,14 @@
<lib>erl_nif</lib>
<libsummary>API functions for an Erlang NIF library</libsummary>
<description>
- <warning><p>The NIF concept is introduced in R13B03 as an
+ <warning><p>The NIF concept was introduced in R13B03 as an
EXPERIMENTAL feature. The interfaces may be changed in any way
- in coming releases. The API introduced in this release is very
- sparse and contains only the most basic functions to read and
- write Erlang terms.
- </p></warning>
+ in coming releases. The API is still sparse and contains only
+ the most basic functions to read and write Erlang terms.
+ </p><p><em>R13B04</em>: The function prototypes of the NIFs
+ have changed to expect <c>argc</c> and <c>argv</c>
+ arguments. The arity of a NIF is by that no longer limited to
+ 3.</p></warning>
<p>A NIF library contains native implementation of some functions
of an erlang module. The native implemented functions (NIFs) are
@@ -56,7 +58,7 @@
/* niftest.c */
#include "erl_nif.h"
-static ERL_NIF_TERM hello(ErlNifEnv* env)
+static ERL_NIF_TERM hello(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
return enif_make_string(env, "Hello world!");
}
@@ -100,8 +102,9 @@ ok
</code>
<p>A better solution for a real module is to take advantage of
- the new attribute <c>on_load</c> to automatically load the NIF
- library when the module is loaded.</p>
+ the new directive <seealso
+ marker="doc/reference_manual:code_loading#on_load">on_load</seealso> to automatically
+ load the NIF library when the module is loaded.</p>
<p>A loaded NIF library is tied to the Erlang module code version
that loaded it. If the module is upgraded with a new version, the
new code will have to load its own NIF library (or maybe choose not
@@ -190,7 +193,7 @@ ok
<title>DATA TYPES</title>
<taglist>
- <tag><marker id="ErlDrvEnv"/>ErlDrvEnv</tag>
+ <tag><marker id="ErlNifEnv"/>ErlNifEnv</tag>
<item>
<p><c>ErlNifEnv</c> contains information about the context in
which a NIF call is made. This pointer should not be
@@ -205,31 +208,28 @@ ok
<p/>
<code type="none">
typedef struct {
- const char* name;
- unsigned arity;
- ERL_NIF_TERM (*fptr)(ErlNifEnv* env, ...);
+ const char* <em>name</em>;
+ unsigned <em>arity</em>;
+ ERL_NIF_TERM (*<em>fptr</em>)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
} ErlNifFunc;
</code>
<p>Describes a NIF by its name, arity and implementation.
<c>fptr</c> is a pointer to the function that implements the
- NIF. The number of arguments must match the arity. A NIF of
- arity 2 will thus look like:</p>
- <p/>
- <code type="none">
-ERL_NIF_TERM my_nif(ErlNifEnv* env, ERL_NIF_TERM arg1, ERL_NIF_TERM arg2)
-{
- /* ... */
-}
-</code>
- <p>The maximum allowed arity for a NIF is 3 in current implementation.</p>
+ NIF. The argument <c>argv</c> of a NIF will contain the
+ function arguments passed to the NIF and <c>argc</c> is the
+ length of the array, i.e. the function arity. <c>argv[N-1]</c>
+ will thus denote the Nth argument to the NIF. Note that the
+ <c>argc</c> argument allows for the same C function to
+ implement several Erlang functions with different arity (but
+ same name probably).</p>
</item>
<tag><marker id="ErlNifBinary"/>ErlNifBinary</tag>
<item>
<p/>
<code type="none">
typedef struct {
- unsigned size;
- unsigned char* data;
+ unsigned <em>size</em>;
+ unsigned char* <em>data</em>;
} ErlNifBinary;
</code>
<p><c>ErlNifBinary</c> contains transient information about an
@@ -249,37 +249,36 @@ typedef struct {
</section>
<funcs>
- <func><name><ret>void*</ret><nametext>enif_get_data(ErlNifEnv* env)</nametext></name>
- <fsummary>Get the private data of a NIF library</fsummary>
- <desc><p>Returns the pointer to the private data that was set by <c>load</c>, <c>reload</c> or <c>upgrade</c>.</p></desc>
- </func>
<func><name><ret>void*</ret><nametext>enif_alloc(ErlNifEnv* env, size_t size)</nametext></name>
<fsummary>Allocate dynamic memory.</fsummary>
- <desc><p>Allocate memory of <c>size</c> bytes.</p></desc>
- </func>
- <func><name><ret>void</ret><nametext>enif_free(ErlNifEnv* env, void* ptr)</nametext></name>
- <fsummary>Free dynamic memory</fsummary>
- <desc><p>Free memory allocated by <c>enif_alloc</c>.</p></desc>
- </func>
- <func><name><ret>int</ret><nametext>enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
- <fsummary>Determine if a term is a binary</fsummary>
- <desc><p>Return true if <c>term</c> is a binary</p></desc>
- </func>
- <func><name><ret>int</ret><nametext>enif_inspect_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, ErlNifBinary* bin)</nametext></name>
- <fsummary>Inspect the content of a binary</fsummary>
- <desc><p>Initialize the structure pointed to by <c>bin</c> with
- transient information about the binary term
- <c>bin_term</c>. Return false if <c>bin_term</c> is not a binary.</p></desc>
+ <desc><p>Allocate memory of <c>size</c> bytes. Return NULL if allocation failed.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin)</nametext></name>
<fsummary>Create a new binary.</fsummary>
<desc><p>Allocate a new binary of size of <c>size</c>
bytes. Initialize the structure pointed to by <c>bin</c> to
- refer to the allocated binary.</p></desc>
+ refer to the allocated binary. Return false if allocation failed.</p></desc>
</func>
- <func><name><ret>void</ret><nametext>enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
- <fsummary>Release a binary.</fsummary>
- <desc><p>Release a binary obtained from <c>enif_alloc_binary</c> or <c>enif_inspect_binary</c>.</p></desc>
+ <func><name><ret>int</ret><nametext>enif_compare(ErlNifEnv* env, ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)</nametext></name>
+ <fsummary>Compare two terms</fsummary>
+ <desc><p>Return an integer less than, equal to, or greater than
+ zero if <c>lhs</c> is found, respectively, to be less than,
+ equal, or greater than <c>rhs</c>. Corresponds to the Erlang
+ operators <c>==</c>, <c>/=</c>, <c>=&lt;</c>, <c>&lt;</c>,
+ <c>&gt;=</c> and <c>&gt;</c> (but <em>not</em> <c>=:=</c> or <c>=/=</c>).</p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_free(ErlNifEnv* env, void* ptr)</nametext></name>
+ <fsummary>Free dynamic memory</fsummary>
+ <desc><p>Free memory allocated by <c>enif_alloc</c>.</p></desc>
+ </func>
+ <func><name><ret>void*</ret><nametext>enif_get_data(ErlNifEnv* env)</nametext></name>
+ <fsummary>Get the private data of a NIF library</fsummary>
+ <desc><p>Return the pointer to the private data that was set by <c>load</c>, <c>reload</c> or <c>upgrade</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_double(ErlNifEnv* env, ERL_NIF_TERM term, double* dp)</nametext></name>
+ <fsummary>Read a floating-point number term.</fsummary>
+ <desc><p>Set <c>*dp</c> to the floating point value of
+ <c>term</c> or return false if <c>term</c> is not a float.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_int(ErlNifEnv* env, ERL_NIF_TERM term, int* ip)</nametext></name>
<fsummary>Read an integer term.</fsummary>
@@ -287,45 +286,80 @@ typedef struct {
<c>term</c> or return false if <c>term</c> is not an integer or is
outside the bounds of type <c>int</c></p></desc>
</func>
- <func><name><ret>int</ret><nametext>enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM term, unsigned long* ip)</nametext></name>
- <fsummary>Read an unsigned long integer</fsummary>
- <desc><p>Set <c>*ip</c> to the unsigned long integer value of
- <c>term</c> or return false if <c>term</c> is not an unsigned
- integer or is outside the bounds of type <c>unsigned long</c></p></desc>
- </func>
<func><name><ret>int</ret><nametext>enif_get_list_cell(ErlNifEnv* env, ERL_NIF_TERM list, ERL_NIF_TERM* head, ERL_NIF_TERM* tail)</nametext></name>
<fsummary>Get head and tail from a list</fsummary>
<desc><p>Set <c>*head</c> and <c>*tail</c> from
<c>list</c> or return false if <c>list</c> is not a non-empty
list.</p></desc>
</func>
- <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
- <fsummary>Make a binary term.</fsummary>
- <desc><p>Make a binary term from <c>bin</c>. Will also release
- the binary.</p></desc>
+ <func><name><ret>int</ret><nametext>enif_get_tuple(ErlNifEnv* env, ERL_NIF_TERM term, int* arity, const ERL_NIF_TERM** array)</nametext></name>
+ <fsummary>Inspect the elements of a tuple.</fsummary>
+ <desc><p>If <c>term</c> is a tuple, set <c>*array</c> to point
+ to an array containing the elements of the tuple and set
+ <c>*arity</c> to the number of elements. Note that the array
+ is read-only an <c>(*array)[N-1]</c> will be the Nth element of
+ the tuple. <c>*array</c> is undefined if the arity of the tuple
+ is zero.</p><p>Return false if <c>term</c> is not a
+ tuple.</p></desc>
</func>
- <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name>
- <fsummary>Make a badarg exception.</fsummary>
- <desc><p>Make a badarg exception to be returned from a NIF.</p></desc>
+ <func><name><ret>int</ret><nametext>enif_get_ulong(ErlNifEnv* env, ERL_NIF_TERM term, unsigned long* ip)</nametext></name>
+ <fsummary>Read an unsigned integer term.</fsummary>
+ <desc><p>Set <c>*ip</c> to the unsigned long integer value of
+ <c>term</c> or return false if <c>term</c> is not an unsigned integer or is
+ outside the bounds of type <c>unsigned long</c></p></desc>
</func>
- <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_int(ErlNifEnv* env, int i)</nametext></name>
- <fsummary>Create an integer term</fsummary>
- <desc><p>Create an integer term.</p></desc>
+ <func><name><ret>int</ret><nametext>enif_inspect_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, ErlNifBinary* bin)</nametext></name>
+ <fsummary>Inspect the content of a binary</fsummary>
+ <desc><p>Initialize the structure pointed to by <c>bin</c> with
+ transient information about the binary term
+ <c>bin_term</c>. Return false if <c>bin_term</c> is not a binary.</p></desc>
</func>
- <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ulong(ErlNifEnv* env, unsigned long i)</nametext></name>
- <fsummary>Create an integer term from an unsigned long int</fsummary>
- <desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc>
+ <func><name><ret>int</ret><nametext>enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is an atom</fsummary>
+ <desc><p>Return true if <c>term</c> is an atom.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a binary</fsummary>
+ <desc><p>Return true if <c>term</c> is a binary</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_identical(ErlNifEnv* env, ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)</nametext></name>
+ <fsummary>Erlang operator =:=</fsummary>
+ <desc><p>Return true if and only if the two terms are
+ identical. Corresponds to the Erlang operators <c>=:=</c> and
+ <c>=/=</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a reference</fsummary>
+ <desc><p>Return true if <c>term</c> is a reference.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom(ErlNifEnv* env, const char* name)</nametext></name>
<fsummary>Create an atom term</fsummary>
<desc><p>Create an atom term from the C-string <c>name</c>. Atom
terms may be saved and used between NIF calls.</p></desc>
</func>
- <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
- <fsummary>Create a tuple term.</fsummary>
- <desc><p>Create a tuple term of arity <c>cnt</c>. Expects
- <c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
- elements of the tuple.</p></desc>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name>
+ <fsummary>Make a badarg exception.</fsummary>
+ <desc><p>Make a badarg exception to be returned from a NIF.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
+ <fsummary>Make a binary term.</fsummary>
+ <desc><p>Make a binary term from <c>bin</c>. Will also release
+ the binary.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_double(ErlNifEnv* env, double d)</nametext></name>
+ <fsummary>Create an floating-point term</fsummary>
+ <desc><p>Create an floating-point term from a <c>double</c>.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom)</nametext></name>
+ <fsummary>Create an existing atom term</fsummary>
+ <desc><p>Try to create the term of an already existing atom from
+ the C-string <c>name</c>. If the atom already exist store the
+ term in <c>*atom</c> and return true, otherwise return
+ false.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_int(ErlNifEnv* env, int i)</nametext></name>
+ <fsummary>Create an integer term</fsummary>
+ <desc><p>Create an integer term.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_list(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
<fsummary>Create a list term.</fsummary>
@@ -337,11 +371,29 @@ typedef struct {
<fsummary>Create a list cell.</fsummary>
<desc><p>Create a list cell <c>[head | tail]</c>.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ref(ErlNifEnv* env)</nametext></name>
+ <fsummary>Create a reference.</fsummary>
+ <desc><p>Create a reference like <seealso marker="erlang#make_ref-0">erlang:make_ref/0</seealso>.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_string(ErlNifEnv* env, const char* string)</nametext></name>
<fsummary>Create a string.</fsummary>
- <desc><p>Creates a list containing the characters of the
+ <desc><p>Create a list containing the characters of the
C-string <c>string</c>.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)</nametext></name>
+ <fsummary>Create a tuple term.</fsummary>
+ <desc><p>Create a tuple term of arity <c>cnt</c>. Expects
+ <c>cnt</c> number of arguments (after <c>cnt</c>) of type ERL_NIF_TERM as the
+ elements of the tuple.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_ulong(ErlNifEnv* env, unsigned long i)</nametext></name>
+ <fsummary>Create an integer term from an unsigned long int</fsummary>
+ <desc><p>Create an integer term from an <c>unsigned long int</c>.</p></desc>
+ </func>
+ <func><name><ret>void</ret><nametext>enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
+ <fsummary>Release a binary.</fsummary>
+ <desc><p>Release a binary obtained from <c>enif_alloc_binary</c> or <c>enif_inspect_binary</c>.</p></desc>
+ </func>
</funcs>
<section>
<title>SEE ALSO</title>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index fd4447009a..871fc0fd63 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -1929,7 +1929,7 @@ os_prompt%</pre>
</desc>
</func>
<func>
- <name>erlang:load_nif(Path, LoadInfo) -> ok | {error, Reason, Text}</name>
+ <name>erlang:load_nif(Path, LoadInfo) -> ok | {error, {Reason, Text}}</name>
<fsummary>Load NIF library</fsummary>
<type>
<v>Path = string()</v>
@@ -1940,9 +1940,10 @@ os_prompt%</pre>
</type>
<desc>
<warning>
- <p>This BIF is currently introduced as an experimental
- feature. The interface may be changed in any way in future
- releases.</p>
+ <p>This BIF is still an experimental feature. The interface
+ may be changed in any way in future releases.</p><p>In
+ R13B03 the return value on failure was
+ <c>{error,Reason,Text}</c>.</p>
</warning>
<p>Loads and links a dynamic library containing native
implemented functions (NIFs) for a module. <c>Path</c> is a
@@ -1957,10 +1958,10 @@ os_prompt%</pre>
<p>The call to <c>load_nif/2</c> must be made
<em>directly</em> from the Erlang code of the module that the
NIF library belongs to.</p>
- <p>It returns either <c>ok</c>, or <c>{error,Reason,Text}</c>
+ <p>It returns either <c>ok</c>, or <c>{error,{Reason,Text}}</c>
if loading fails. <c>Reason</c> is one of the atoms below,
while <c>Text</c> is a human readable string that may give
- some more information about the failure:</p>
+ some more information about the failure.</p>
<taglist>
<tag><c>load_failed</c></tag>
<item>
@@ -4641,7 +4642,7 @@ true</pre>
<fsummary>Split a binary into two</fsummary>
<type>
<v>Bin = Bin1 = Bin2 = binary()</v>
- <v>Pos = 1..byte_size(Bin)</v>
+ <v>Pos = 0..byte_size(Bin)</v>
</type>
<desc>
<p>Returns a tuple containing the binaries which are the result
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index a2061134a5..903e1e96ba 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -402,7 +402,7 @@ endif
$(RM) -f $(TARGET)/*/*/*.c $(TARGET)/*/*/*.h $(TARGET)/*/*/*.S
$(RM) -f $(ERL_TOP)/erts/emulator/obj/$(TARGET)/*/*/*.o
$(RM) -f $(BINDIR)/beam $(BINDIR)/beam.*
- $(RM) -f $(BINDIR)/child_setup $(BINDIR)/child_setup.*
+ $(RM) -rf $(BINDIR)/child_setup $(BINDIR)/child_setup.*
$(RM) -f $(BINDIR)/hipe_mkliterals $(BINDIR)/hipe_mkliterals.*
@set -e ; cd zlib && $(MAKE) clean
@set -e ; cd pcre && $(MAKE) clean
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index dcaa43b51c..4ebb8853be 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -974,10 +974,6 @@ static int hibernate(Process* c_p, Eterm module, Eterm function,
static Eterm* call_fun(Process* p, int arity, Eterm* reg, Eterm args);
static Eterm* apply_fun(Process* p, Eterm fun, Eterm args, Eterm* reg);
static Eterm new_fun(Process* p, Eterm* reg, ErlFunEntry* fe, int num_free);
-static BIF_RETTYPE nif_dispatcher_0(Process* p, Uint* I);
-static BIF_RETTYPE nif_dispatcher_1(Process* p, Eterm arg1, Uint* I);
-static BIF_RETTYPE nif_dispatcher_2(Process* p, Eterm arg1, Eterm arg2, Uint* I);
-static BIF_RETTYPE nif_dispatcher_3(Process* p, Eterm arg1, Eterm arg2, Eterm arg3, Uint* I);
#if defined(_OSE_) || defined(VXWORKS)
static int init_done;
@@ -2949,11 +2945,38 @@ void process_main(void)
OpCase(call_nif):
{
- static void* const dispatchers[4] = {
- nif_dispatcher_0, nif_dispatcher_1, nif_dispatcher_2, nif_dispatcher_3
- };
- BifFunction vbf = dispatchers[I[-1]];
- goto apply_bif_or_nif;
+ /*
+ * call_nif is always first instruction in function:
+ *
+ * I[-3]: Module
+ * I[-2]: Function
+ * I[-1]: Arity
+ * I[0]: &&call_nif
+ * I[1]: Function pointer to NIF function
+ * I[2]: priv_data pointer
+ */
+ BifFunction vbf;
+
+ c_p->current = I-3; /* current and vbf set to please handle_error */
+ SWAPOUT;
+ c_p->fcalls = FCALLS - 1;
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ tmp_arg2 = I[-1];
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
+
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p));
+ {
+ typedef Eterm NifF(struct enif_environment_t*, int argc, Eterm argv[]);
+ NifF* fp = vbf = (NifF*) I[1];
+ struct enif_environment_t env;
+ erts_pre_nif(&env, c_p, (void*)I[2]);
+ reg[0] = r(0);
+ tmp_arg1 = (*fp)(&env, tmp_arg2, reg);
+ erts_post_nif(&env);
+ }
+ ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(tmp_arg1));
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ goto apply_bif_or_nif_epilogue;
OpCase(apply_bif):
/*
@@ -2966,17 +2989,15 @@ void process_main(void)
* code[3]: &&apply_bif
* code[4]: Function pointer to BIF function
*/
- vbf = (BifFunction) Arg(0);
- apply_bif_or_nif:
c_p->current = I-3; /* In case we apply process_info/1,2 or load_nif/1 */
c_p->i = I; /* In case we apply check_process_code/2. */
c_p->arity = 0; /* To allow garbage collection on ourselves
* (check_process_code/2).
*/
-
SWAPOUT;
c_p->fcalls = FCALLS - 1;
+ vbf = (BifFunction) Arg(0);
PROCESS_MAIN_CHK_LOCKS(c_p);
tmp_arg2 = I[-1];
ASSERT(tmp_arg2 <= 3);
@@ -3019,6 +3040,7 @@ void process_main(void)
break;
}
}
+apply_bif_or_nif_epilogue:
ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
ERTS_HOLE_CHECK(c_p);
if (c_p->mbuf) {
@@ -5245,6 +5267,7 @@ save_stacktrace(Process* c_p, Eterm* pc, Eterm* reg, BifFunction bf,
* The Bif does not really exist (no BIF entry). It is a
* TRAP and traps are called through apply_bif, which also
* sets c_p->current (luckily).
+ * OR it is a NIF called by call_nif where current is also set.
*/
ASSERT(c_p->current);
s->current = c_p->current;
@@ -6148,51 +6171,3 @@ erts_current_reductions(Process *current, Process *p)
}
}
-static BIF_RETTYPE nif_dispatcher_0(Process* p, Uint* I)
-{
- typedef Eterm NifF(struct enif_environment_t*);
- NifF* fp = (NifF*) I[1];
- struct enif_environment_t env;
- Eterm ret;
- erts_pre_nif(&env, p, (void*)I[2]);
- ret = (*fp)(&env);
- erts_post_nif(&env);
- return ret;
-}
-
-static BIF_RETTYPE nif_dispatcher_1(Process* p, Eterm arg1, Uint* I)
-{
- typedef Eterm NifF(struct enif_environment_t*, Eterm);
- NifF* fp = (NifF*) I[1];
- struct enif_environment_t env;
- Eterm ret;
- erts_pre_nif(&env, p, (void*)I[2]);
- ret = (*fp)(&env, arg1);
- erts_post_nif(&env);
- return ret;
-}
-
-static BIF_RETTYPE nif_dispatcher_2(Process* p, Eterm arg1, Eterm arg2, Uint* I)
-{
- typedef Eterm NifF(struct enif_environment_t*, Eterm, Eterm);
- NifF* fp = (NifF*) I[1];
- struct enif_environment_t env;
- Eterm ret;
- erts_pre_nif(&env, p, (void*)I[2]);
- ret = (*fp)(&env, arg1, arg2);
- erts_post_nif(&env);
- return ret;
-}
-
-static BIF_RETTYPE nif_dispatcher_3(Process* p, Eterm arg1, Eterm arg2, Eterm arg3, Uint* I)
-{
- typedef Eterm NifF(struct enif_environment_t*, Eterm, Eterm, Eterm);
- NifF* fp = (NifF*) I[1];
- struct enif_environment_t env;
- Eterm ret;
- erts_pre_nif(&env, p, (void*)I[2]);
- ret = (*fp)(&env, arg1, arg2, arg3);
- erts_post_nif(&env);
- return ret;
-}
-
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 5ea47e16f5..cc69977b79 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -703,6 +703,8 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
erts_fdprintf(fd, "System version: ");
erts_print_system_version(fd, NULL, NULL);
erts_fdprintf(fd, "%s\n", "Compiled: " ERLANG_COMPILE_DATE);
+ erts_fdprintf(fd, "Taints: ");
+ erts_print_nif_taints(fd, NULL);
erts_fdprintf(fd, "Atoms: %d\n", atom_table_size());
info(fd, NULL); /* General system info */
if (process_tab != NULL) /* XXX true at init */
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index fa4454a3f3..2cb93112ae 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -35,13 +35,6 @@
#include <limits.h>
-/*
-static ERTS_INLINE Eterm* alloc_heap(ErlNifEnv* env, unsigned need)
-{
- return HAlloc(env->proc, need);
-}
-*/
-
#define MIN_HEAP_FRAG_SZ 200
static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need);
@@ -116,12 +109,21 @@ void enif_free(ErlNifEnv* env, void* ptr)
erts_free(ERTS_ALC_T_NIF, ptr);
}
+int enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_atom(term);
+}
int enif_is_binary(ErlNifEnv* env, ERL_NIF_TERM term)
{
return is_binary(term) && (binary_bitsize(term) % 8 == 0);
}
-
+
+int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_ref(term);
+}
+
int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin)
{
@@ -157,6 +159,25 @@ int enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin)
return 1;
}
+int enif_realloc_binary(ErlNifEnv* env, ErlNifBinary* bin, unsigned size)
+{
+ Binary* oldbin;
+ Binary* newbin;
+ ASSERT(bin->ref_bin != NULL);
+
+ oldbin = (Binary*) bin->ref_bin;
+ newbin = (Binary *) erts_bin_realloc_fnf(oldbin, size);
+ if (!newbin) {
+ return 0;
+ }
+ newbin->orig_size = size;
+ bin->ref_bin = newbin;
+ bin->data = (unsigned char*) newbin->orig_bytes;
+ bin->size = size;
+ return 1;
+}
+
+
void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)
{
if (bin->ref_bin == NULL) {
@@ -177,6 +198,28 @@ void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)
#endif
}
+int enif_is_identical(ErlNifEnv* env, Eterm lhs, Eterm rhs)
+{
+ return EQ(lhs,rhs);
+}
+
+int enif_compare(ErlNifEnv* env, Eterm lhs, Eterm rhs)
+{
+ return cmp(lhs,rhs);
+}
+
+int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, Eterm** array)
+{
+ Eterm* ptr;
+ if (is_not_tuple(tpl)) {
+ return 0;
+ }
+ ptr = tuple_val(tpl);
+ *arity = arityval(*ptr);
+ *array = ptr+1;
+ return 1;
+}
+
Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)
{
if (bin->ref_bin == NULL) {
@@ -203,7 +246,7 @@ Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)
}
}
-ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env)
+Eterm enif_make_badarg(ErlNifEnv* env)
{
BIF_ERROR(env->proc, BADARG);
}
@@ -212,7 +255,7 @@ ERL_NIF_TERM enif_make_badarg(ErlNifEnv* env)
int enif_get_int(ErlNifEnv* env, Eterm term, int* ip)
{
#if SIZEOF_INT == SIZEOF_VOID_P
- return term_to_Sint(term, ip);
+ return term_to_Sint(term, (Sint*)ip);
#elif SIZEOF_LONG == SIZEOF_VOID_P
Sint i;
if (!term_to_Sint(term, &i) || i < INT_MIN || i > INT_MAX) {
@@ -234,6 +277,17 @@ int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip)
#endif
}
+int enif_get_double(ErlNifEnv* env, Eterm term, double* dp)
+{
+ FloatDef f;
+ if (is_not_float(term)) {
+ return 0;
+ }
+ GET_DOUBLE(term, f);
+ *dp = f.fd;
+ return 1;
+}
+
int enif_get_list_cell(ErlNifEnv* env, Eterm term, Eterm* head, Eterm* tail)
{
Eterm* val;
@@ -267,12 +321,24 @@ ERL_NIF_TERM enif_make_ulong(ErlNifEnv* env, unsigned long i)
}
+ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d)
+{
+ Eterm* hp = alloc_heap(env,FLOAT_SIZE_OBJECT);
+ FloatDef f;
+ f.fd = d;
+ PUT_DOUBLE(f, hp);
+ return make_float(hp);
+}
ERL_NIF_TERM enif_make_atom(ErlNifEnv* env, const char* name)
{
return am_atom_put(name, sys_strlen(name));
}
+int enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom)
+{
+ return erts_atom_get(name, sys_strlen(name), atom);
+}
ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
{
@@ -320,13 +386,43 @@ ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...)
ERL_NIF_TERM enif_make_string(ErlNifEnv* env, const char* string)
{
- Sint n = strlen(string);
+ Sint n = sys_strlen(string);
Eterm* hp = alloc_heap(env,n*2);
return erts_bld_string_n(&hp,NULL,string,n);
}
+ERL_NIF_TERM enif_make_ref(ErlNifEnv* env)
+{
+ Eterm* hp = alloc_heap(env, REF_THING_SIZE);
+ return erts_make_ref_in_buffer(hp);
+}
+
+#if 0 /* To be continued... */
+typedef struct enif_handle_type_t
+{
+ struct enif_handle_type_t* next;
+ struct enif_handle_type_t* prev;
+ const char* name;
+ void (*dtor)(void* obj);
+ erts_smp_atomic_t ref_cnt; /* num of handles of this type */
+}ErlNifHandleType;
+
+ErlNifHandleType*
+enif_create_handle_type(ErlNifEnv* env, const char* type_name,
+ void (*dtor)(void *))
+{
+
+}
+
+ERL_NIF_TERM enif_make_handle(ErlNifEnv* env, ErlNifHandleType* htype, void* obj)
+{
+}
+int enif_get_handle(ErlNifEnv* env, ERL_NIF_TERM term, void** objp)
+{
+}
+#endif
/***************************************************************************
** load_nif/2 **
@@ -361,7 +457,7 @@ static void refresh_cached_nif_data(Eterm* mod_code,
ErlNifFunc* func = &mod_nif->entry->funcs[i];
Uint* code_ptr;
- erts_atom_get(func->name, strlen(func->name), &f_atom);
+ erts_atom_get(func->name, sys_strlen(func->name), &f_atom);
code_ptr = *get_func_pp(mod_code, f_atom, func->arity);
code_ptr[5+2] = (Uint) mod_nif->data;
}
@@ -411,6 +507,18 @@ Eterm erts_nif_taints(Process* p)
return list;
}
+void erts_print_nif_taints(int to, void* to_arg)
+{
+ struct tainted_module_t* t;
+ const char* delim = "";
+ for (t=first_tainted_module ; t!=NULL; t=t->next) {
+ const Atom* atom = atom_tab(atom_val(t->module_atom));
+ erts_print(to,to_arg,"%s%.*s", delim, atom->len, atom->name);
+ delim = ",";
+ }
+ erts_print(to,to_arg,"\n");
+}
+
static Eterm load_nif_error(Process* p, const char* atom, const char* format, ...)
{
@@ -428,7 +536,8 @@ static Eterm load_nif_error(Process* p, const char* atom, const char* format, ..
for (;;) {
Eterm txt = erts_bld_string_n(hpp, &sz, dsbufp->str, dsbufp->str_len);
- ret = erts_bld_tuple(hpp, szp, 3, am_error, mkatom(atom), txt);
+ ret = erts_bld_tuple(hpp, szp, 2, am_error,
+ erts_bld_tuple(hpp, szp, 2, mkatom(atom), txt));
if (hpp != NULL) {
break;
}
@@ -489,8 +598,13 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
"module '%T' not allowed", mod_atom);
}
else if ((err=erts_sys_ddll_open2(lib_name, &handle, &errdesc)) != ERL_DE_NO_ERROR) {
- ret = load_nif_error(BIF_P, "load_failed", "Failed to load NIF library"
- " %s: '%s'", lib_name, errdesc.str);
+ const char slogan[] = "Failed to load NIF library";
+ if (strstr(errdesc.str, lib_name) != NULL) {
+ ret = load_nif_error(BIF_P, "load_failed", "%s: '%s'", slogan, errdesc.str);
+ }
+ else {
+ ret = load_nif_error(BIF_P, "load_failed", "%s %s: '%s'", slogan, lib_name, errdesc.str);
+ }
}
else if (erts_sys_ddll_load_nif_init(handle, &init_func, &errdesc) != ERL_DE_NO_ERROR) {
ret = load_nif_error(BIF_P, bad_lib, "Failed to find library init"
@@ -517,12 +631,8 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
for (i=0; i < entry->num_of_funcs && ret==am_ok; i++) {
Uint** code_pp;
ErlNifFunc* f = &entry->funcs[i];
- if (f->arity > 3) {
- ret = load_nif_error(BIF_P,bad_lib,"Function arity too high for NIF %s/%u",
- f->name, f->arity);
- }
- else if (!erts_atom_get(f->name, strlen(f->name), &f_atom)
- || (code_pp = get_func_pp(mod->code, f_atom, f->arity))==NULL) {
+ if (!erts_atom_get(f->name, sys_strlen(f->name), &f_atom)
+ || (code_pp = get_func_pp(mod->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);
}
@@ -612,7 +722,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
for (i=0; i < entry->num_of_funcs; i++)
{
Uint* code_ptr;
- erts_atom_get(entry->funcs[i].name, strlen(entry->funcs[i].name), &f_atom);
+ erts_atom_get(entry->funcs[i].name, sys_strlen(entry->funcs[i].name), &f_atom);
code_ptr = *get_func_pp(mod->code, f_atom, entry->funcs[i].arity);
if (code_ptr[1] == 0) {
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 8650b7ce47..e5e6d65c0e 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -20,23 +20,27 @@
/* Include file for writers of Native Implemented Functions.
*/
-#define ERL_NIF_MAJOR_VERSION 0
-#define ERL_NIF_MINOR_VERSION 1
+/* Version history:
+** 0.1: R13B03
+** 1.0: R13B04
+*/
+#define ERL_NIF_MAJOR_VERSION 1
+#define ERL_NIF_MINOR_VERSION 0
#include <stdlib.h>
typedef unsigned long ERL_NIF_TERM;
+struct enif_environment_t;
+typedef struct enif_environment_t ErlNifEnv;
+
typedef struct
{
const char* name;
unsigned arity;
- void* fptr; //ERL_NIF_TERM (*fptr)(void*, ...);
+ ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
}ErlNifFunc;
-struct enif_environment_t;
-typedef struct enif_environment_t ErlNifEnv;
-
typedef struct enif_entry_t
{
int major;
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 400c1822cc..7556806ce4 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -25,44 +25,68 @@
ERL_NIF_API_FUNC_DECL(void*,enif_get_data,(ErlNifEnv*));
ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(ErlNifEnv*, size_t size));
ERL_NIF_API_FUNC_DECL(void,enif_free,(ErlNifEnv*, void* ptr));
+ERL_NIF_API_FUNC_DECL(int,enif_is_atom,(ErlNifEnv*, ERL_NIF_TERM term));
ERL_NIF_API_FUNC_DECL(int,enif_is_binary,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_ref,(ErlNifEnv*, ERL_NIF_TERM term));
ERL_NIF_API_FUNC_DECL(int,enif_inspect_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, ErlNifBinary* bin));
ERL_NIF_API_FUNC_DECL(int,enif_alloc_binary,(ErlNifEnv*, unsigned size, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_realloc_binary,(ErlNifEnv*, ErlNifBinary* bin, unsigned size));
ERL_NIF_API_FUNC_DECL(void,enif_release_binary,(ErlNifEnv*, ErlNifBinary* bin));
ERL_NIF_API_FUNC_DECL(int,enif_get_int,(ErlNifEnv*, ERL_NIF_TERM term, int* ip));
ERL_NIF_API_FUNC_DECL(int,enif_get_ulong,(ErlNifEnv*, ERL_NIF_TERM term, unsigned long* ip));
+ERL_NIF_API_FUNC_DECL(int,enif_get_double,(ErlNifEnv*, ERL_NIF_TERM term, double* dp));
ERL_NIF_API_FUNC_DECL(int,enif_get_list_cell,(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM* head, ERL_NIF_TERM* tail));
+ERL_NIF_API_FUNC_DECL(int,enif_get_tuple,(ErlNifEnv* env, ERL_NIF_TERM tpl, int* arity, ERL_NIF_TERM** array));
+ERL_NIF_API_FUNC_DECL(int,enif_is_identical,(ErlNifEnv* env, ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
+ERL_NIF_API_FUNC_DECL(int,enif_compare,(ErlNifEnv* env, ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_binary,(ErlNifEnv* env, ErlNifBinary* bin));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_badarg,(ErlNifEnv* env));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int,(ErlNifEnv* env, int i));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ulong,(ErlNifEnv* env, unsigned long i));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_double,(ErlNifEnv* env, double d));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_atom,(ErlNifEnv* env, const char* name));
+ERL_NIF_API_FUNC_DECL(int,enif_make_existing_atom,(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple,(ErlNifEnv* env, unsigned cnt, ...));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list,(ErlNifEnv* env, unsigned cnt, ...));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_cell,(ErlNifEnv* env, ERL_NIF_TERM car, ERL_NIF_TERM cdr));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string,(ErlNifEnv* env, const char* string));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ref,(ErlNifEnv* env));
+/*
+** Add last to keep compatibility on Windows!!!
+*/
#endif
#ifdef ERL_NIF_API_FUNC_MACRO
# define enif_get_data ERL_NIF_API_FUNC_MACRO(enif_get_data)
# define enif_alloc ERL_NIF_API_FUNC_MACRO(enif_alloc)
# define enif_free ERL_NIF_API_FUNC_MACRO(enif_free)
+# define enif_is_atom ERL_NIF_API_FUNC_MACRO(enif_is_atom)
# define enif_is_binary ERL_NIF_API_FUNC_MACRO(enif_is_binary)
+# define enif_is_ref ERL_NIF_API_FUNC_MACRO(enif_is_ref)
# define enif_inspect_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_binary)
# define enif_alloc_binary ERL_NIF_API_FUNC_MACRO(enif_alloc_binary)
+# define enif_realloc_binary ERL_NIF_API_FUNC_MACRO(enif_realloc_binary)
# define enif_release_binary ERL_NIF_API_FUNC_MACRO(enif_release_binary)
# define enif_get_int ERL_NIF_API_FUNC_MACRO(enif_get_int)
# define enif_get_ulong ERL_NIF_API_FUNC_MACRO(enif_get_ulong)
+# define enif_get_double ERL_NIF_API_FUNC_MACRO(enif_get_double)
+# define enif_get_tuple ERL_NIF_API_FUNC_MACRO(enif_get_tuple)
# define enif_get_list_cell ERL_NIF_API_FUNC_MACRO(enif_get_list_cell)
+# define enif_is_identical ERL_NIF_API_FUNC_MACRO(enif_is_identical)
+# define enif_compare ERL_NIF_API_FUNC_MACRO(enif_compare)
# define enif_make_binary ERL_NIF_API_FUNC_MACRO(enif_make_binary)
# define enif_make_badarg ERL_NIF_API_FUNC_MACRO(enif_make_badarg)
# define enif_make_int ERL_NIF_API_FUNC_MACRO(enif_make_int)
# define enif_make_ulong ERL_NIF_API_FUNC_MACRO(enif_make_ulong)
+# define enif_make_double ERL_NIF_API_FUNC_MACRO(enif_make_double)
# define enif_make_atom ERL_NIF_API_FUNC_MACRO(enif_make_atom)
+# define enif_make_existing_atom ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom)
# define enif_make_tuple ERL_NIF_API_FUNC_MACRO(enif_make_tuple)
# define enif_make_list ERL_NIF_API_FUNC_MACRO(enif_make_list)
# define enif_make_list_cell ERL_NIF_API_FUNC_MACRO(enif_make_list_cell)
# define enif_make_string ERL_NIF_API_FUNC_MACRO(enif_make_string)
+# define enif_make_ref ERL_NIF_API_FUNC_MACRO(enif_make_ref)
+
#endif
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 9960172366..a4afe0574f 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -219,7 +219,7 @@ ErtsSchedulerData *erts_scheduler_data;
ErtsAlignedRunQueue *erts_aligned_run_queues;
Uint erts_no_run_queues;
-typedef struct {
+typedef union {
ErtsSchedulerData esd;
char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsSchedulerData))];
} ErtsAlignedSchedulerData;
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 7bae1e4efc..7597eb5e31 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -339,9 +339,14 @@ do { \
struct ErtsSchedulerData_ {
#ifdef ERTS_SMP
- ethr_tid tid; /* Thread id */
+ /*
+ * Keep X registers first (so we get as many low
+ * numbered registers as possible in the same cache
+ * line).
+ */
Eterm save_reg[ERTS_X_REGS_ALLOCATED]; /* X registers */
FloatDef freg[MAX_REG]; /* Floating point registers. */
+ ethr_tid tid; /* Thread id */
struct erl_bits_state erl_bits_state; /* erl_bits.c state */
void *match_pseudo_process; /* erl_db_util.c:db_prog_match() */
Process *free_process;
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 1b64e23174..62a788cbff 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -86,7 +86,8 @@ struct enif_environment_t /* ErlNifEnv */
};
extern void erts_pre_nif(struct enif_environment_t*, Process*, void* nif_data);
extern void erts_post_nif(struct enif_environment_t* env);
-extern Eterm erts_nif_taints(Process* p);
+extern Eterm erts_nif_taints(Process* p);
+extern void erts_print_nif_taints(int to, void* to_arg);
/*
* Port Specific Data.
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 71cb6a36cc..4b949523fa 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -239,6 +239,11 @@ EXTERN_FUNCTION(int, real_printf, (const char *fmt, ...));
** Sint16: A signed integer of 16 bits exactly.
*/
+#if !((SIZEOF_VOID_P >= 4) && (SIZEOF_VOID_P == SIZEOF_SIZE_T) \
+ && ((SIZEOF_VOID_P == SIZEOF_INT) || (SIZEOF_VOID_P == SIZEOF_LONG)))
+#error Cannot handle this combination of int/long/void*/size_t sizes
+#endif
+
#if SIZEOF_VOID_P == 8
#undef ARCH_32
#define ARCH_64
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index b7b577da5b..c6e23ee647 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -1205,8 +1205,8 @@ static void *realloc_wrapper(void *current, size_t size){
/* For AssocID, 4 bytes should be enough -- checked by "init": */
# define GET_ASSOC_ID get_int32
# define ASSOC_ID_LEN 4
-# define LOAD_ASSOC_ID LOAD_INT
-# define LOAD_ASSOC_ID_CNT LOAD_INT_CNT
+# define LOAD_ASSOC_ID LOAD_UINT
+# define LOAD_ASSOC_ID_CNT LOAD_UINT_CNT
# define SCTP_ANC_BUFF_SIZE INET_DEF_BUFFER/2 /* XXX: not very good... */
#endif
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 213ff6637a..e47161fcbc 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -24,12 +24,13 @@
-include("test_server.hrl").
-export([all/1, fin_per_testcase/2, basic/1, reload/1, upgrade/1, heap_frag/1,
- neg/1]).
+ types/1, many_args/1, neg/1]).
+-export([many_args_100/100]).
-define(nif_stub,nif_stub_error(?LINE)).
all(suite) ->
- [basic, reload, upgrade, heap_frag, neg].
+ [basic, reload, upgrade, heap_frag, types, many_args, neg].
fin_per_testcase(_Func, _Config) ->
P1 = code:purge(nif_mod),
@@ -184,19 +185,68 @@ heap_frag_do(N, Max) ->
L = list_seq(N),
heap_frag_do(((N*5) div 4) + 1, Max).
+types(doc) -> ["Type tests"];
+types(suite) -> [];
+types(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+ ?line ok = type_test(),
+ lists:foreach(fun(Tpl) ->
+ Lst = erlang:tuple_to_list(Tpl),
+ Lst = tuple_2_list(Tpl)
+ end,
+ [{},{ok},{{}},{[],{}},{1,2,3,4,5}]),
+ Stuff = [[],{},0,0.0,(1 bsl 100),(fun()-> ok end),make_ref(),self()],
+ [eq_cmp(A,clone(B)) || A<-Stuff, B<-Stuff],
+ ok.
+
+clone(X) ->
+ binary_to_term(term_to_binary(X)).
+
+eq_cmp(A,B) ->
+ eq_cmp_do(A,B),
+ eq_cmp_do([A,B],[A,B]),
+ eq_cmp_do({A,B},{A,B}).
+
+eq_cmp_do(A,B) ->
+ %%?t:format("compare ~p and ~p\n",[A,B]),
+ Eq = (A =:= B),
+ ?line Eq = is_identical(A,B),
+ ?line Cmp = if
+ A < B -> -1;
+ A == B -> 0;
+ A > B -> 1
+ end,
+ ?line Cmp = case compare(A,B) of
+ C when is_integer(C), C < 0 -> -1;
+ 0 -> 0;
+ C when is_integer(C) -> 1
+ end,
+ ok.
+
+
+many_args(doc) -> ["Test NIF with many arguments"];
+many_args(suite) -> [];
+many_args(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config ,1),
+ ?line ok = apply(?MODULE,many_args_100,lists:seq(1,100)),
+ ?line ok = many_args_100(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100),
+ ok.
+
+
+
neg(doc) -> ["Negative testing of load_nif"];
neg(suite) -> [];
neg(Config) when is_list(Config) ->
?line {'EXIT',{badarg,_}} = (catch erlang:load_nif(badarg, 0)),
- ?line {error,load_failed,_} = erlang:load_nif("pink_unicorn", 0),
+ ?line {error,{load_failed,_}} = erlang:load_nif("pink_unicorn", 0),
?line Data = ?config(data_dir, Config),
?line File = filename:join(Data, "nif_mod"),
?line {ok,nif_mod,Bin} = compile:file(File, [binary,return_errors]),
?line {module,nif_mod} = erlang:load_module(nif_mod,Bin),
- ?line {error,bad_lib,_} = nif_mod:load_nif_lib(Config, no_init),
+ ?line {error,{bad_lib,_}} = nif_mod:load_nif_lib(Config, no_init),
?line ok.
@@ -230,6 +280,11 @@ call_history() -> ?nif_stub.
hold_nif_mod_priv_data(_Ptr) -> ?nif_stub.
nif_mod_call_history() -> ?nif_stub.
list_seq(_To) -> ?nif_stub.
+type_test() -> ?nif_stub.
+tuple_2_list(_) -> ?nif_stub.
+is_identical(_,_) -> ?nif_stub.
+compare(_,_) -> ?nif_stub.
+many_args_100(_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_,_) -> ?nif_stub.
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 852495e234..4532062dce 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -1,6 +1,9 @@
#include "erl_nif.h"
+
+#include <stdio.h>
#include <string.h>
#include <assert.h>
+#include <limits.h>
#include "nif_mod.h"
@@ -65,7 +68,7 @@ static void unload(ErlNifEnv* env, void* priv_data)
}
}
-static ERL_NIF_TERM lib_version(ErlNifEnv* env)
+static ERL_NIF_TERM lib_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ADD_CALL("lib_version");
return enif_make_int(env, NIF_SUITE_LIB_VER);
@@ -89,19 +92,19 @@ static ERL_NIF_TERM make_call_history(ErlNifEnv* env, CallInfo** headp)
return list;
}
-static ERL_NIF_TERM call_history(ErlNifEnv* env)
+static ERL_NIF_TERM call_history(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
PrivData* data = (PrivData*) enif_get_data(env);
return make_call_history(env,&data->call_history);
}
-static ERL_NIF_TERM hold_nif_mod_priv_data(ErlNifEnv* env, ERL_NIF_TERM a1)
+static ERL_NIF_TERM hold_nif_mod_priv_data(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
PrivData* data = (PrivData*) enif_get_data(env);
unsigned long ptr_as_ulong;
- if (!enif_get_ulong(env,a1,&ptr_as_ulong)) {
+ if (!enif_get_ulong(env,argv[0],&ptr_as_ulong)) {
return enif_make_badarg(env);
}
if (data->nif_mod != NULL && --(data->nif_mod->ref_cnt) == 0) {
@@ -111,7 +114,7 @@ static ERL_NIF_TERM hold_nif_mod_priv_data(ErlNifEnv* env, ERL_NIF_TERM a1)
return enif_make_int(env,++(data->nif_mod->ref_cnt));
}
-static ERL_NIF_TERM nif_mod_call_history(ErlNifEnv* env)
+static ERL_NIF_TERM nif_mod_call_history(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
PrivData* data = (PrivData*) enif_get_data(env);
@@ -121,11 +124,11 @@ static ERL_NIF_TERM nif_mod_call_history(ErlNifEnv* env)
return make_call_history(env,&data->nif_mod->call_history);
}
-static ERL_NIF_TERM list_seq(ErlNifEnv* env, ERL_NIF_TERM a1)
+static ERL_NIF_TERM list_seq(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ERL_NIF_TERM list;
int n;
- if (!enif_get_int(env, a1, &n)) {
+ if (!enif_get_int(env, argv[0], &n)) {
return enif_make_badarg(env);
}
list = enif_make_list(env, 0); /* NIL */
@@ -136,13 +139,183 @@ static ERL_NIF_TERM list_seq(ErlNifEnv* env, ERL_NIF_TERM a1)
return list;
}
+static int test_int(ErlNifEnv* env, int i1)
+{
+ int i2 = 0;
+ ERL_NIF_TERM int_term = enif_make_int(env, i1);
+ if (!enif_get_int(env,int_term, &i2) || i1 != i2) {
+ fprintf(stderr, "test_int(%d) ...FAILED i2=%d\r\n", i1, i2);
+ return 0;
+ }
+ return 1;
+}
+
+static int test_ulong(ErlNifEnv* env, unsigned long i1)
+{
+ unsigned long i2 = 0;
+ ERL_NIF_TERM int_term = enif_make_ulong(env, i1);
+ if (!enif_get_ulong(env,int_term, &i2) || i1 != i2) {
+ fprintf(stderr, "SVERK: test_ulong(%lu) ...FAILED i2=%lu\r\n", i1, i2);
+ return 0;
+ }
+ return 1;
+}
+
+static int test_double(ErlNifEnv* env, double d1)
+{
+ double d2 = 0;
+ ERL_NIF_TERM term = enif_make_double(env, d1);
+ if (!enif_get_double(env,term, &d2) || d1 != d2) {
+ fprintf(stderr, "SVERK: test_double(%e) ...FAILED i2=%e\r\n", d1, d2);
+ return 0;
+ }
+ return 1;
+}
+
+#define TAG_BITS 4
+#define SMALL_BITS (sizeof(void*)*8 - TAG_BITS)
+#define MAX_SMALL ((1L << (SMALL_BITS-1))-1)
+#define MIN_SMALL (-(1L << (SMALL_BITS-1)))
+
+static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int i;
+ unsigned long u;
+ double d;
+ ERL_NIF_TERM atom, ref1, ref2;
+
+ i = INT_MIN;
+ do {
+ if (!test_int(env,i)) {
+ goto error;
+ }
+ i += ~i / 3 + 1;
+ } while (i < 0);
+ i = INT_MAX;
+ do {
+ if (!test_int(env,i)) {
+ goto error;
+ }
+ i -= i / 3 + 1;
+ } while (i >= 0);
+
+ u = ULONG_MAX;
+ for (;;) {
+ if (!test_ulong(env,u)) {
+
+ }
+ if (u == 0) break;
+ u -= u / 3 + 1;
+ }
+
+ if (MAX_SMALL < INT_MAX) { /* 32-bit */
+ for (i=-10 ; i <= 10; i++) {
+ if (!test_int(env,MAX_SMALL+i)) {
+ goto error;
+ }
+ }
+ for (i=-10 ; i <= 10; i++) {
+ if (!test_int(env,MIN_SMALL+i)) {
+ goto error;
+ }
+ }
+ }
+ assert((MAX_SMALL < INT_MAX) == (MIN_SMALL > INT_MIN));
+
+ for (u=0 ; u < 10; u++) {
+ if (!test_ulong(env,MAX_SMALL+u) || !test_ulong(env,MAX_SMALL-u)) {
+ goto error;
+ }
+ }
+
+ for (d=3.141592e-100 ; d < 1e100 ; d *= 9.97) {
+ if (!test_double(env,d) || !test_double(env,-d)) {
+ goto error;
+ }
+ }
+
+ if (!enif_make_existing_atom(env,"nif_SUITE", &atom)
+ || !enif_is_identical(env,atom,enif_make_atom(env,"nif_SUITE"))) {
+ fprintf(stderr, "SVERK: nif_SUITE not an atom?\r\n");
+ goto error;
+ }
+ for (i=2; i; i--) {
+ if (enif_make_existing_atom(env,"nif_SUITE_pink_unicorn", &atom)) {
+ fprintf(stderr, "SVERK: pink unicorn exist?\r\n");
+ goto error;
+ }
+ }
+ ref1 = enif_make_ref(env);
+ ref2 = enif_make_ref(env);
+ if (!enif_is_ref(env,ref1) || !enif_is_ref(env,ref2)
+ || enif_is_identical(env,ref1,ref2) || enif_compare(env,ref1,ref2)==0) {
+ fprintf(stderr, "SVERK: strange refs?\r\n");
+ }
+ return enif_make_atom(env,"ok");
+
+error:
+ return enif_make_atom(env,"error");
+}
+
+static ERL_NIF_TERM tuple_2_list(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int arity = -1;
+ ERL_NIF_TERM* ptr;
+ ERL_NIF_TERM list = enif_make_list(env,0);
+
+ if (argc!=1 || !enif_get_tuple(env,argv[0],&arity,&ptr)) {
+ return enif_make_badarg(env);
+ }
+ while (--arity >= 0) {
+ list = enif_make_list_cell(env,ptr[arity],list);
+ }
+ return list;
+}
+
+static ERL_NIF_TERM is_identical(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ if (argc != 2) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_atom(env, (enif_is_identical(env,argv[0],argv[1]) ?
+ "true" : "false"));
+}
+
+static ERL_NIF_TERM compare(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ if (argc != 2) {
+ return enif_make_badarg(env);
+ }
+ return enif_make_int(env, enif_compare(env,argv[0],argv[1]));
+}
+
+static ERL_NIF_TERM many_args_100(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int i, k;
+ if (argc == 100) {
+ for (i=1; i<=100; i++) {
+ if (!enif_get_int(env,argv[i-1],&k) || k!=i) {
+ goto badarg;
+ }
+ }
+ return enif_make_atom(env,"ok");
+ }
+badarg:
+ return enif_make_badarg(env);
+}
+
static ErlNifFunc nif_funcs[] =
{
{"lib_version", 0, lib_version},
{"call_history", 0, call_history},
{"hold_nif_mod_priv_data", 1, hold_nif_mod_priv_data},
{"nif_mod_call_history", 0, nif_mod_call_history},
- {"list_seq", 1, list_seq}
+ {"list_seq", 1, list_seq},
+ {"type_test", 0, type_test},
+ {"tuple_2_list", 1, tuple_2_list},
+ {"is_identical",2,is_identical},
+ {"compare",2,compare},
+ {"many_args_100", 100, many_args_100}
};
ERL_NIF_INIT(nif_SUITE,nif_funcs,load,reload,upgrade,unload)
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.c b/erts/emulator/test/nif_SUITE_data/nif_mod.c
index 18f676335a..2f2267cf78 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c
@@ -58,13 +58,13 @@ static void unload(ErlNifEnv* env, void* priv_data)
}
}
-static ERL_NIF_TERM lib_version(ErlNifEnv* env)
+static ERL_NIF_TERM lib_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ADD_CALL("lib_version");
return enif_make_int(env, NIF_LIB_VER);
}
-static ERL_NIF_TERM call_history(ErlNifEnv* env)
+static ERL_NIF_TERM call_history(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
NifModPrivData* data = (NifModPrivData*) enif_get_data(env);
ERL_NIF_TERM list = enif_make_list(env, 0); /* NIL */
@@ -81,7 +81,7 @@ static ERL_NIF_TERM call_history(ErlNifEnv* env)
return list;
}
-static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env)
+static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ADD_CALL("get_priv_data_ptr");
return enif_make_ulong(env, (unsigned long)enif_get_data(env));
diff --git a/erts/emulator/test/trace_nif_SUITE_data/trace_nif.c b/erts/emulator/test/trace_nif_SUITE_data/trace_nif.c
index 732f1010ae..26f2420b8b 100644
--- a/erts/emulator/test/trace_nif_SUITE_data/trace_nif.c
+++ b/erts/emulator/test/trace_nif_SUITE_data/trace_nif.c
@@ -20,18 +20,18 @@ static void unload(ErlNifEnv* env, void* priv_data)
{
}
-static ERL_NIF_TERM nif_0(ErlNifEnv* env)
+static ERL_NIF_TERM nif_0(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
return enif_make_tuple(env,2,
enif_make_atom(env,"ok"),
enif_make_list(env,0));
}
-static ERL_NIF_TERM nif_1(ErlNifEnv* env, ERL_NIF_TERM a1)
+static ERL_NIF_TERM nif_1(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
return enif_make_tuple(env,2,
enif_make_atom(env,"ok"),
- enif_make_list(env,1,a1));
+ enif_make_list(env,1,argv[0]));
}
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index 2b7e8a6dde..4a859c3094 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -753,8 +753,8 @@ sub comment {
print "$prefix$line\n";
}
} else {
- print "$prefix Warning: Do not edit this file. It was automatically\n";
- print "$prefix generated by '$prog' on ", (scalar localtime), ".\n";
+ print "$prefix Warning: Do not edit this file.\n";
+ print "$prefix Auto-generated by '$prog'.\n";
}
if ($lang eq 'C') {
print " */\n";
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index b120b44579..65fcf9bacb 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-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%
*/
/*
@@ -294,6 +294,7 @@ struct enode {
char protocol; /* 0 = tcp/ipv4 */
unsigned short highvsn; /* 0 = OTP-R3 erts-4.6.x, 1 = OTP-R4 erts-4.7.x*/
unsigned short lowvsn;
+ int extralen;
char extra[MAXSYMLEN+1];
};
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index b71e27cffd..a033fab244 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -1,20 +1,20 @@
/* -*- c-indent-level: 2; c-continued-statement-offset: 2 -*- */
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 1998-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 1998-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%
*/
@@ -99,7 +99,7 @@ static int conn_close_fd(EpmdVars*,int);
static void node_init(EpmdVars*);
static Node *node_reg(EpmdVars*,char*,int,int);
-static Node *node_reg2(EpmdVars*,char*, int, int, unsigned char, unsigned char, int, int, char*);
+static Node *node_reg2(EpmdVars*,char*, int, int, unsigned char, unsigned char, int, int, int, char*);
static int node_unreg(EpmdVars*,char*);
static int node_unreg_sock(EpmdVars*,int);
@@ -558,11 +558,11 @@ static void do_request(g, fd, s, buf, bsize)
}
name = &buf[11];
name[namelen]='\000';
- extra = &buf[11+namelen+1];
+ extra = &buf[11+namelen+2];
extra[extralen]='\000';
wbuf[0] = EPMD_ALIVE2_RESP;
if ((node = node_reg2(g, name, fd, eport, nodetype, protocol,
- highvsn, lowvsn, extra)) == NULL) {
+ highvsn, lowvsn, extralen, extra)) == NULL) {
wbuf[1] = 1; /* error */
put_int16(99, wbuf+2);
} else {
@@ -622,10 +622,10 @@ static void do_request(g, fd, s, buf, bsize)
offset = 12;
strcpy(wbuf + offset,node->symname);
offset += strlen(node->symname);
- put_int16(strlen(node->extra),wbuf + offset);
+ put_int16(node->extralen,wbuf + offset);
offset += 2;
- strcpy(wbuf + offset,node->extra);
- offset += (strlen(node->extra)-1);
+ memcpy(wbuf + offset,node->extra,node->extralen);
+ offset += node->extralen;
if (reply(g, fd, wbuf, offset) != offset)
{
dbg_tty_printf(g,1,"** failed to send PORT2_RESP (ok) for \"%s\"",name);
@@ -994,7 +994,7 @@ static int node_unreg_sock(EpmdVars *g,int fd)
static Node *node_reg(EpmdVars *g,char *name,int fd, int port)
{
- return node_reg2(g, name, fd, port, 0, 0, 0, 0, NULL);
+ return node_reg2(g, name, fd, port, 0, 0, 0, 0, 0, NULL);
}
static Node *node_reg2(EpmdVars *g,
@@ -1005,6 +1005,7 @@ static Node *node_reg2(EpmdVars *g,
unsigned char protocol,
int highvsn,
int lowvsn,
+ int extralen,
char* extra)
{
Node *prev; /* Point to previous node or NULL */
@@ -1103,7 +1104,8 @@ static Node *node_reg2(EpmdVars *g,
node->protocol = protocol;
node->highvsn = highvsn;
node->lowvsn = lowvsn;
- strcpy(node->extra,extra);
+ node->extralen = extralen;
+ memcpy(node->extra,extra,extralen);
strcpy(node->symname,name);
FD_SET(fd,&g->orig_read_mask);
diff --git a/erts/etc/unix/to_erl.c b/erts/etc/unix/to_erl.c
index 588d127445..886b301997 100644
--- a/erts/etc/unix/to_erl.c
+++ b/erts/etc/unix/to_erl.c
@@ -164,7 +164,7 @@ int main(int argc, char **argv)
dirp = opendir(pipename);
if(!dirp) {
- fprintf(stderr, "Can't access pipe directory %s.\n", pipename);
+ fprintf(stderr, "Can't access pipe directory %s: %s\n", pipename, strerror(errno));
exit(1);
}
@@ -205,7 +205,7 @@ int main(int argc, char **argv)
#ifdef DEBUG
fprintf(stderr, "Could not open FIFO %s for reading.\n", FIFO1);
#endif
- fprintf(stderr, "No running Erlang on pipe %s.\n", pipename);
+ fprintf(stderr, "No running Erlang on pipe %s: %s\n", pipename, strerror(errno));
exit(1);
}
#ifdef DEBUG
@@ -216,7 +216,7 @@ int main(int argc, char **argv)
#ifdef DEBUG
fprintf(stderr, "Could not open FIFO %s for writing.\n", FIFO2);
#endif
- fprintf(stderr, "No running Erlang on pipe %s.\n", pipename);
+ fprintf(stderr, "No running Erlang on pipe %s: %s\n", pipename, strerror(errno));
close(rfd);
exit(1);
}
diff --git a/erts/etc/win32/cygwin_tools/vc/mc.sh b/erts/etc/win32/cygwin_tools/vc/mc.sh
index 813b59947b..676b072655 100755
--- a/erts/etc/win32/cygwin_tools/vc/mc.sh
+++ b/erts/etc/win32/cygwin_tools/vc/mc.sh
@@ -24,7 +24,7 @@ CMD=""
OUTPUT_DIRNAME=""
# Find the correct mc.exe. This could be done by the configure script,
-# But as we seldom use the resource compiler, it might as well be done here...
+# But as we seldom use the message compiler, it might as well be done here...
MCC=""
save_ifs=$IFS
IFS=:
@@ -32,7 +32,7 @@ for p in $PATH; do
if [ -f $p/mc.exe ]; then
if [ -n "`$p/mc.exe -? 2>&1 >/dev/null </dev/null \
| grep -i \"message compiler\"`" ]; then
- MCC=$p/mc.exe
+ MCC=`echo "$p/mc.exe" | sed 's/ /\\\\ /g'`
fi
fi
done
@@ -68,8 +68,8 @@ while test -n "$1" ; do
done
p=$$
if [ "X$MC_SH_DEBUG_LOG" != "X" ]; then
- echo rc.sh "$SAVE" >>$MC_SH_DEBUG_LOG
- echo rc.exe $CMD >>$MC_SH_DEBUG_LOG
+ echo mc.sh "$SAVE" >>$MC_SH_DEBUG_LOG
+ echo mc.exe $CMD >>$MC_SH_DEBUG_LOG
fi
if [ -n "$OUTPUT_DIRNAME" ]; then
cd $OUTPUT_DIRNAME
diff --git a/erts/etc/win32/cygwin_tools/vc/rc.sh b/erts/etc/win32/cygwin_tools/vc/rc.sh
index 748de48890..6a6921c49e 100755
--- a/erts/etc/win32/cygwin_tools/vc/rc.sh
+++ b/erts/etc/win32/cygwin_tools/vc/rc.sh
@@ -30,8 +30,8 @@ save_ifs=$IFS
IFS=:
for p in $PATH; do
if [ -f $p/rc.exe ]; then
- if [ -n "`$p/rc.exe -? 2>&1 | grep -i "resource compiler"`" ]; then
- RCC=$p/rc.exe
+ if [ -n "`$p/rc.exe -? 2>&1 | grep -i "resource compiler"`" ]; then
+ RCC=`echo "$p/rc.exe" | sed 's/ /\\\\ /g'`
fi
fi
done
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index a031c90188..d7134967bf 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 39452f53d6..f490fe7c3d 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 7b6bafd1af..39118a0109 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 af44a8c9b9..4680d645cb 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 9391aa45cd..2cacb6808c 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 b7be06e6bc..aa9b255ebb 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 6e1230d649..0e7adad9e8 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 4d9996cc74..93b05172d8 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 6f92b319b7..552121d485 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -51,6 +51,7 @@
-export([await_proc_exit/3]).
-deprecated([hash/2]).
+-deprecated([concat_binary/1]).
-compile(nowarn_bif_clash).
diff --git a/erts/preloaded/src/init.erl b/erts/preloaded/src/init.erl
index c6f4c62f63..c0b3d286e8 100644
--- a/erts/preloaded/src/init.erl
+++ b/erts/preloaded/src/init.erl
@@ -1357,10 +1357,7 @@ run_on_load_handlers([M|Ms]) ->
{Pid,Ref} = spawn_monitor(Fun),
receive
{'DOWN',Ref,process,Pid,OnLoadRes} ->
- Keep = if
- is_boolean(OnLoadRes) -> OnLoadRes;
- true -> false
- end,
+ Keep = OnLoadRes =:= ok,
erlang:finish_after_on_load(M, Keep),
case Keep of
false ->
diff --git a/lib/.gitignore b/lib/.gitignore
new file mode 100644
index 0000000000..0cb938ea7c
--- /dev/null
+++ b/lib/.gitignore
@@ -0,0 +1,471 @@
+# erl_interface
+
+/erl_interface/bin
+/erl_interface/obj.mt
+/erl_interface/obj.st
+/erl_interface/obj
+
+# megaco
+
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.erl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3a.hrl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.erl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3b.hrl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.erl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_prev3c.hrl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.erl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v1.hrl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.erl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v2.hrl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.erl
+/megaco/src/binary/megaco_ber_bin_drv_media_gateway_control_v3.hrl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.erl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3a.hrl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.erl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3b.hrl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.erl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_prev3c.hrl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.erl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_v1.hrl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.erl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_v2.hrl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.erl
+/megaco/src/binary/megaco_ber_bin_media_gateway_control_v3.hrl
+/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.erl
+/megaco/src/binary/megaco_ber_media_gateway_control_prev3a.hrl
+/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.erl
+/megaco/src/binary/megaco_ber_media_gateway_control_prev3b.hrl
+/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.erl
+/megaco/src/binary/megaco_ber_media_gateway_control_prev3c.hrl
+/megaco/src/binary/megaco_ber_media_gateway_control_v1.erl
+/megaco/src/binary/megaco_ber_media_gateway_control_v1.hrl
+/megaco/src/binary/megaco_ber_media_gateway_control_v2.erl
+/megaco/src/binary/megaco_ber_media_gateway_control_v2.hrl
+/megaco/src/binary/megaco_ber_media_gateway_control_v3.erl
+/megaco/src/binary/megaco_ber_media_gateway_control_v3.hrl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.erl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3a.hrl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.erl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3b.hrl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.erl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_prev3c.hrl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.erl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v1.hrl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.erl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v2.hrl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.erl
+/megaco/src/binary/megaco_per_bin_drv_media_gateway_control_v3.hrl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.erl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3a.hrl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.erl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3b.hrl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.erl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_prev3c.hrl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.erl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_v1.hrl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.erl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_v2.hrl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.erl
+/megaco/src/binary/megaco_per_bin_media_gateway_control_v3.hrl
+/megaco/src/binary/megaco_per_media_gateway_control_prev3a.erl
+/megaco/src/binary/megaco_per_media_gateway_control_prev3a.hrl
+/megaco/src/binary/megaco_per_media_gateway_control_prev3b.erl
+/megaco/src/binary/megaco_per_media_gateway_control_prev3b.hrl
+/megaco/src/binary/megaco_per_media_gateway_control_prev3c.erl
+/megaco/src/binary/megaco_per_media_gateway_control_prev3c.hrl
+/megaco/src/binary/megaco_per_media_gateway_control_v1.erl
+/megaco/src/binary/megaco_per_media_gateway_control_v1.hrl
+/megaco/src/binary/megaco_per_media_gateway_control_v2.erl
+/megaco/src/binary/megaco_per_media_gateway_control_v2.hrl
+/megaco/src/binary/megaco_per_media_gateway_control_v3.erl
+/megaco/src/binary/megaco_per_media_gateway_control_v3.hrl
+/megaco/src/binary/prebuild.skip
+/megaco/src/flex/megaco_flex_scanner_drv.c
+/megaco/src/flex/megaco_flex_scanner_drv.flex
+/megaco/src/flex/megaco_flex_scanner_drv_mt.c
+/megaco/src/flex/megaco_flex_scanner_drv_mt.flex
+/megaco/src/text/megaco_text_mini_parser.erl
+/megaco/src/text/megaco_text_parser_prev3a.erl
+/megaco/src/text/megaco_text_parser_prev3b.erl
+/megaco/src/text/megaco_text_parser_prev3c.erl
+/megaco/src/text/megaco_text_parser_v1.erl
+/megaco/src/text/megaco_text_parser_v2.erl
+/megaco/src/text/megaco_text_parser_v3.erl
+
+# orber & cos* applications
+
+/cosEvent/include/CosEventChannelAdmin.hrl
+/cosEvent/include/CosEventChannelAdmin_ConsumerAdmin.hrl
+/cosEvent/include/CosEventChannelAdmin_EventChannel.hrl
+/cosEvent/include/CosEventChannelAdmin_ProxyPullConsumer.hrl
+/cosEvent/include/CosEventChannelAdmin_ProxyPullSupplier.hrl
+/cosEvent/include/CosEventChannelAdmin_ProxyPushConsumer.hrl
+/cosEvent/include/CosEventChannelAdmin_ProxyPushSupplier.hrl
+/cosEvent/include/CosEventChannelAdmin_SupplierAdmin.hrl
+/cosEvent/include/CosEventComm.hrl
+/cosEvent/include/CosEventComm_PullConsumer.hrl
+/cosEvent/include/CosEventComm_PullSupplier.hrl
+/cosEvent/include/CosEventComm_PushConsumer.hrl
+/cosEvent/include/CosEventComm_PushSupplier.hrl
+/cosEvent/include/oe_CosEventChannelAdmin.hrl
+/cosEvent/include/oe_CosEventComm.hrl
+/cosEvent/src/CosEventChannelAdmin_AlreadyConnected.erl
+/cosEvent/src/CosEventChannelAdmin_ConsumerAdmin.erl
+/cosEvent/src/CosEventChannelAdmin_EventChannel.erl
+/cosEvent/src/CosEventChannelAdmin_ProxyPullConsumer.erl
+/cosEvent/src/CosEventChannelAdmin_ProxyPullSupplier.erl
+/cosEvent/src/CosEventChannelAdmin_ProxyPushConsumer.erl
+/cosEvent/src/CosEventChannelAdmin_ProxyPushSupplier.erl
+/cosEvent/src/CosEventChannelAdmin_SupplierAdmin.erl
+/cosEvent/src/CosEventChannelAdmin_TypeError.erl
+/cosEvent/src/CosEventComm_Disconnected.erl
+/cosEvent/src/CosEventComm_PullConsumer.erl
+/cosEvent/src/CosEventComm_PullSupplier.erl
+/cosEvent/src/CosEventComm_PushConsumer.erl
+/cosEvent/src/CosEventComm_PushSupplier.erl
+/cosEvent/src/oe_CosEventChannelAdmin.erl
+/cosEvent/src/oe_CosEventComm.erl
+/cosEvent/src/oe_CosEventComm_CAdmin.erl
+/cosEvent/src/oe_CosEventComm_CAdmin.hrl
+/cosEvent/src/oe_CosEventComm_Channel.erl
+/cosEvent/src/oe_CosEventComm_Channel.hrl
+/cosEvent/src/oe_CosEventComm_Event.erl
+/cosEvent/src/oe_CosEventComm_Event.hrl
+/cosEvent/src/oe_CosEventComm_PullerS.erl
+/cosEvent/src/oe_CosEventComm_PullerS.hrl
+/cosEvent/src/oe_CosEventComm_PusherS.erl
+/cosEvent/src/oe_CosEventComm_PusherS.hrl
+/cosEvent/src/oe_cosEventApp.erl
+/cosEvent/src/oe_cosEventApp.hrl
+/cosEventDomain/include/CosEventDomainAdmin.hrl
+/cosEventDomain/include/CosEventDomainAdmin_EventDomain.hrl
+/cosEventDomain/include/CosEventDomainAdmin_EventDomainFactory.hrl
+/cosEventDomain/include/oe_CosEventDomainAdmin.hrl
+/cosEventDomain/src/CosEventDomainAdmin.erl
+/cosEventDomain/src/CosEventDomainAdmin_AlreadyExists.erl
+/cosEventDomain/src/CosEventDomainAdmin_Connection.erl
+/cosEventDomain/src/CosEventDomainAdmin_ConnectionIDSeq.erl
+/cosEventDomain/src/CosEventDomainAdmin_ConnectionNotFound.erl
+/cosEventDomain/src/CosEventDomainAdmin_CycleCreationForbidden.erl
+/cosEventDomain/src/CosEventDomainAdmin_CycleSeq.erl
+/cosEventDomain/src/CosEventDomainAdmin_DiamondCreationForbidden.erl
+/cosEventDomain/src/CosEventDomainAdmin_DiamondSeq.erl
+/cosEventDomain/src/CosEventDomainAdmin_DomainIDSeq.erl
+/cosEventDomain/src/CosEventDomainAdmin_DomainNotFound.erl
+/cosEventDomain/src/CosEventDomainAdmin_EventDomain.erl
+/cosEventDomain/src/CosEventDomainAdmin_EventDomainFactory.erl
+/cosEventDomain/src/CosEventDomainAdmin_MemberIDSeq.erl
+/cosEventDomain/src/CosEventDomainAdmin_RouteSeq.erl
+/cosEventDomain/src/oe_CosEventDomainAdmin.erl
+/cosFileTransfer/include/CosFileTransfer.hrl
+/cosFileTransfer/include/CosFileTransfer_Directory.hrl
+/cosFileTransfer/include/CosFileTransfer_File.hrl
+/cosFileTransfer/include/CosFileTransfer_FileIterator.hrl
+/cosFileTransfer/include/CosFileTransfer_FileTransferSession.hrl
+/cosFileTransfer/include/CosFileTransfer_VirtualFileSystem.hrl
+/cosFileTransfer/include/oe_CosFileTransfer.hrl
+/cosFileTransfer/src/CosFileTransfer.erl
+/cosFileTransfer/src/CosFileTransfer_AccessLevel.erl
+/cosFileTransfer/src/CosFileTransfer_CommandNotImplementedException.erl
+/cosFileTransfer/src/CosFileTransfer_Directory.erl
+/cosFileTransfer/src/CosFileTransfer_File.erl
+/cosFileTransfer/src/CosFileTransfer_FileIterator.erl
+/cosFileTransfer/src/CosFileTransfer_FileList.erl
+/cosFileTransfer/src/CosFileTransfer_FileNameList.erl
+/cosFileTransfer/src/CosFileTransfer_FileNotFoundException.erl
+/cosFileTransfer/src/CosFileTransfer_FileTransferSession.erl
+/cosFileTransfer/src/CosFileTransfer_FileWrapper.erl
+/cosFileTransfer/src/CosFileTransfer_IllegalOperationException.erl
+/cosFileTransfer/src/CosFileTransfer_ProtocolAddressList.erl
+/cosFileTransfer/src/CosFileTransfer_ProtocolSupport.erl
+/cosFileTransfer/src/CosFileTransfer_RequestFailureException.erl
+/cosFileTransfer/src/CosFileTransfer_SessionException.erl
+/cosFileTransfer/src/CosFileTransfer_SupportedProtocolAddresses.erl
+/cosFileTransfer/src/CosFileTransfer_TransferException.erl
+/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem.erl
+/cosFileTransfer/src/CosFileTransfer_VirtualFileSystem_ContentList.erl
+/cosFileTransfer/src/oe_CosFileTransfer.erl
+/cosNotification/include/CosNotification.hrl
+/cosNotification/include/CosNotification_AdminPropertiesAdmin.hrl
+/cosNotification/include/CosNotification_QoSAdmin.hrl
+/cosNotification/include/CosNotifyChannelAdmin.hrl
+/cosNotification/include/CosNotifyChannelAdmin_ConsumerAdmin.hrl
+/cosNotification/include/CosNotifyChannelAdmin_EventChannel.hrl
+/cosNotification/include/CosNotifyChannelAdmin_EventChannelFactory.hrl
+/cosNotification/include/CosNotifyChannelAdmin_ProxyConsumer.hrl
+/cosNotification/include/CosNotifyChannelAdmin_ProxyPullConsumer.hrl
+/cosNotification/include/CosNotifyChannelAdmin_ProxyPullSupplier.hrl
+/cosNotification/include/CosNotifyChannelAdmin_ProxyPushConsumer.hrl
+/cosNotification/include/CosNotifyChannelAdmin_ProxyPushSupplier.hrl
+/cosNotification/include/CosNotifyChannelAdmin_ProxySupplier.hrl
+/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPullConsumer.hrl
+/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPullSupplier.hrl
+/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPushConsumer.hrl
+/cosNotification/include/CosNotifyChannelAdmin_SequenceProxyPushSupplier.hrl
+/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPullConsumer.hrl
+/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPullSupplier.hrl
+/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPushConsumer.hrl
+/cosNotification/include/CosNotifyChannelAdmin_StructuredProxyPushSupplier.hrl
+/cosNotification/include/CosNotifyChannelAdmin_SupplierAdmin.hrl
+/cosNotification/include/CosNotifyComm.hrl
+/cosNotification/include/CosNotifyComm_NotifyPublish.hrl
+/cosNotification/include/CosNotifyComm_NotifySubscribe.hrl
+/cosNotification/include/CosNotifyComm_PullConsumer.hrl
+/cosNotification/include/CosNotifyComm_PullSupplier.hrl
+/cosNotification/include/CosNotifyComm_PushConsumer.hrl
+/cosNotification/include/CosNotifyComm_PushSupplier.hrl
+/cosNotification/include/CosNotifyComm_SequencePullConsumer.hrl
+/cosNotification/include/CosNotifyComm_SequencePullSupplier.hrl
+/cosNotification/include/CosNotifyComm_SequencePushConsumer.hrl
+/cosNotification/include/CosNotifyComm_SequencePushSupplier.hrl
+/cosNotification/include/CosNotifyComm_StructuredPullConsumer.hrl
+/cosNotification/include/CosNotifyComm_StructuredPullSupplier.hrl
+/cosNotification/include/CosNotifyComm_StructuredPushConsumer.hrl
+/cosNotification/include/CosNotifyComm_StructuredPushSupplier.hrl
+/cosNotification/include/CosNotifyFilter.hrl
+/cosNotification/include/CosNotifyFilter_Filter.hrl
+/cosNotification/include/CosNotifyFilter_FilterAdmin.hrl
+/cosNotification/include/CosNotifyFilter_FilterFactory.hrl
+/cosNotification/include/CosNotifyFilter_MappingFilter.hrl
+/cosNotification/include/oe_CosNotification.hrl
+/cosNotification/include/oe_CosNotifyChannelAdmin.hrl
+/cosNotification/include/oe_CosNotifyComm.hrl
+/cosNotification/include/oe_CosNotifyFilter.hrl
+/cosNotification/src/CosNotification.erl
+/cosNotification/src/CosNotification_AdminPropertiesAdmin.erl
+/cosNotification/src/CosNotification_EventBatch.erl
+/cosNotification/src/CosNotification_EventHeader.erl
+/cosNotification/src/CosNotification_EventType.erl
+/cosNotification/src/CosNotification_EventTypeSeq.erl
+/cosNotification/src/CosNotification_FixedEventHeader.erl
+/cosNotification/src/CosNotification_NamedPropertyRange.erl
+/cosNotification/src/CosNotification_NamedPropertyRangeSeq.erl
+/cosNotification/src/CosNotification_Property.erl
+/cosNotification/src/CosNotification_PropertyError.erl
+/cosNotification/src/CosNotification_PropertyErrorSeq.erl
+/cosNotification/src/CosNotification_PropertyRange.erl
+/cosNotification/src/CosNotification_PropertySeq.erl
+/cosNotification/src/CosNotification_QoSAdmin.erl
+/cosNotification/src/CosNotification_StructuredEvent.erl
+/cosNotification/src/CosNotification_UnsupportedAdmin.erl
+/cosNotification/src/CosNotification_UnsupportedQoS.erl
+/cosNotification/src/CosNotifyChannelAdmin_AdminIDSeq.erl
+/cosNotification/src/CosNotifyChannelAdmin_AdminLimit.erl
+/cosNotification/src/CosNotifyChannelAdmin_AdminLimitExceeded.erl
+/cosNotification/src/CosNotifyChannelAdmin_AdminNotFound.erl
+/cosNotification/src/CosNotifyChannelAdmin_ChannelIDSeq.erl
+/cosNotification/src/CosNotifyChannelAdmin_ChannelNotFound.erl
+/cosNotification/src/CosNotifyChannelAdmin_ConnectionAlreadyActive.erl
+/cosNotification/src/CosNotifyChannelAdmin_ConnectionAlreadyInactive.erl
+/cosNotification/src/CosNotifyChannelAdmin_ConsumerAdmin.erl
+/cosNotification/src/CosNotifyChannelAdmin_EventChannel.erl
+/cosNotification/src/CosNotifyChannelAdmin_EventChannelFactory.erl
+/cosNotification/src/CosNotifyChannelAdmin_NotConnected.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxyConsumer.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxyIDSeq.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxyNotFound.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxyPullConsumer.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxyPullSupplier.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxyPushConsumer.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxyPushSupplier.erl
+/cosNotification/src/CosNotifyChannelAdmin_ProxySupplier.erl
+/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPullConsumer.erl
+/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPullSupplier.erl
+/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPushConsumer.erl
+/cosNotification/src/CosNotifyChannelAdmin_SequenceProxyPushSupplier.erl
+/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPullConsumer.erl
+/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPullSupplier.erl
+/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPushConsumer.erl
+/cosNotification/src/CosNotifyChannelAdmin_StructuredProxyPushSupplier.erl
+/cosNotification/src/CosNotifyChannelAdmin_SupplierAdmin.erl
+/cosNotification/src/CosNotifyComm_InvalidEventType.erl
+/cosNotification/src/CosNotifyComm_NotifyPublish.erl
+/cosNotification/src/CosNotifyComm_NotifySubscribe.erl
+/cosNotification/src/CosNotifyComm_PullConsumer.erl
+/cosNotification/src/CosNotifyComm_PullSupplier.erl
+/cosNotification/src/CosNotifyComm_PushConsumer.erl
+/cosNotification/src/CosNotifyComm_PushSupplier.erl
+/cosNotification/src/CosNotifyComm_SequencePullConsumer.erl
+/cosNotification/src/CosNotifyComm_SequencePullSupplier.erl
+/cosNotification/src/CosNotifyComm_SequencePushConsumer.erl
+/cosNotification/src/CosNotifyComm_SequencePushSupplier.erl
+/cosNotification/src/CosNotifyComm_StructuredPullConsumer.erl
+/cosNotification/src/CosNotifyComm_StructuredPullSupplier.erl
+/cosNotification/src/CosNotifyComm_StructuredPushConsumer.erl
+/cosNotification/src/CosNotifyComm_StructuredPushSupplier.erl
+/cosNotification/src/CosNotifyFilter_CallbackIDSeq.erl
+/cosNotification/src/CosNotifyFilter_CallbackNotFound.erl
+/cosNotification/src/CosNotifyFilter_ConstraintExp.erl
+/cosNotification/src/CosNotifyFilter_ConstraintExpSeq.erl
+/cosNotification/src/CosNotifyFilter_ConstraintIDSeq.erl
+/cosNotification/src/CosNotifyFilter_ConstraintInfo.erl
+/cosNotification/src/CosNotifyFilter_ConstraintInfoSeq.erl
+/cosNotification/src/CosNotifyFilter_ConstraintNotFound.erl
+/cosNotification/src/CosNotifyFilter_DuplicateConstraintID.erl
+/cosNotification/src/CosNotifyFilter_Filter.erl
+/cosNotification/src/CosNotifyFilter_FilterAdmin.erl
+/cosNotification/src/CosNotifyFilter_FilterFactory.erl
+/cosNotification/src/CosNotifyFilter_FilterIDSeq.erl
+/cosNotification/src/CosNotifyFilter_FilterNotFound.erl
+/cosNotification/src/CosNotifyFilter_InvalidConstraint.erl
+/cosNotification/src/CosNotifyFilter_InvalidGrammar.erl
+/cosNotification/src/CosNotifyFilter_InvalidValue.erl
+/cosNotification/src/CosNotifyFilter_MappingConstraintInfo.erl
+/cosNotification/src/CosNotifyFilter_MappingConstraintInfoSeq.erl
+/cosNotification/src/CosNotifyFilter_MappingConstraintPair.erl
+/cosNotification/src/CosNotifyFilter_MappingConstraintPairSeq.erl
+/cosNotification/src/CosNotifyFilter_MappingFilter.erl
+/cosNotification/src/CosNotifyFilter_UnsupportedFilterableData.erl
+/cosNotification/src/cosNotification_Grammar.erl
+/cosNotification/src/oe_CosNotification.erl
+/cosNotification/src/oe_CosNotificationComm.hrl
+/cosNotification/src/oe_CosNotificationComm_Event.erl
+/cosNotification/src/oe_CosNotificationComm_Event.hrl
+/cosNotification/src/oe_CosNotifyChannelAdmin.erl
+/cosNotification/src/oe_CosNotifyComm.erl
+/cosNotification/src/oe_CosNotifyFilter.erl
+/cosNotification/src/oe_cosNotificationAppComm.erl
+/cosNotification/src/oe_cosNotificationAppComm.hrl
+/cosProperty/include/CosPropertyService.hrl
+/cosProperty/include/CosPropertyService_PropertiesIterator.hrl
+/cosProperty/include/CosPropertyService_PropertyNamesIterator.hrl
+/cosProperty/include/CosPropertyService_PropertySet.hrl
+/cosProperty/include/CosPropertyService_PropertySetDef.hrl
+/cosProperty/include/CosPropertyService_PropertySetDefFactory.hrl
+/cosProperty/include/CosPropertyService_PropertySetFactory.hrl
+/cosProperty/include/oe_CosProperty.hrl
+/cosProperty/src/CosPropertyService_ConflictingProperty.erl
+/cosProperty/src/CosPropertyService_ConstraintNotSupported.erl
+/cosProperty/src/CosPropertyService_FixedProperty.erl
+/cosProperty/src/CosPropertyService_InvalidPropertyName.erl
+/cosProperty/src/CosPropertyService_MultipleExceptions.erl
+/cosProperty/src/CosPropertyService_Properties.erl
+/cosProperty/src/CosPropertyService_PropertiesIterator.erl
+/cosProperty/src/CosPropertyService_Property.erl
+/cosProperty/src/CosPropertyService_PropertyDef.erl
+/cosProperty/src/CosPropertyService_PropertyDefs.erl
+/cosProperty/src/CosPropertyService_PropertyException.erl
+/cosProperty/src/CosPropertyService_PropertyExceptions.erl
+/cosProperty/src/CosPropertyService_PropertyMode.erl
+/cosProperty/src/CosPropertyService_PropertyModes.erl
+/cosProperty/src/CosPropertyService_PropertyNames.erl
+/cosProperty/src/CosPropertyService_PropertyNamesIterator.erl
+/cosProperty/src/CosPropertyService_PropertyNotFound.erl
+/cosProperty/src/CosPropertyService_PropertySet.erl
+/cosProperty/src/CosPropertyService_PropertySetDef.erl
+/cosProperty/src/CosPropertyService_PropertySetDefFactory.erl
+/cosProperty/src/CosPropertyService_PropertySetFactory.erl
+/cosProperty/src/CosPropertyService_PropertyTypes.erl
+/cosProperty/src/CosPropertyService_ReadOnlyProperty.erl
+/cosProperty/src/CosPropertyService_UnsupportedMode.erl
+/cosProperty/src/CosPropertyService_UnsupportedProperty.erl
+/cosProperty/src/CosPropertyService_UnsupportedTypeCode.erl
+/cosProperty/src/oe_CosProperty.erl
+/cosTime/include/CosTime.hrl
+/cosTime/include/CosTime_TIO.hrl
+/cosTime/include/CosTime_TimeService.hrl
+/cosTime/include/CosTime_UTO.hrl
+/cosTime/include/CosTimerEvent.hrl
+/cosTime/include/CosTimerEvent_TimerEventHandler.hrl
+/cosTime/include/CosTimerEvent_TimerEventService.hrl
+/cosTime/include/TimeBase.hrl
+/cosTime/include/oe_CosTime.hrl
+/cosTime/include/oe_CosTimerEvent.hrl
+/cosTime/include/oe_TimeBase.hrl
+/cosTime/src/CosTime_TIO.erl
+/cosTime/src/CosTime_TimeService.erl
+/cosTime/src/CosTime_TimeUnavailable.erl
+/cosTime/src/CosTime_UTO.erl
+/cosTime/src/CosTimerEvent_TimerEventHandler.erl
+/cosTime/src/CosTimerEvent_TimerEventService.erl
+/cosTime/src/CosTimerEvent_TimerEventT.erl
+/cosTime/src/TimeBase_IntervalT.erl
+/cosTime/src/TimeBase_UtcT.erl
+/cosTime/src/oe_CosTime.erl
+/cosTime/src/oe_CosTimerEvent.erl
+/cosTime/src/oe_TimeBase.erl
+/cosTransactions/include/CosTransactions.hrl
+/cosTransactions/include/CosTransactions_Control.hrl
+/cosTransactions/include/CosTransactions_Coordinator.hrl
+/cosTransactions/include/CosTransactions_RecoveryCoordinator.hrl
+/cosTransactions/include/CosTransactions_Resource.hrl
+/cosTransactions/include/CosTransactions_SubtransactionAwareResource.hrl
+/cosTransactions/include/CosTransactions_Terminator.hrl
+/cosTransactions/include/CosTransactions_TransactionFactory.hrl
+/cosTransactions/include/ETraP.hrl
+/cosTransactions/include/ETraP_Server.hrl
+/cosTransactions/include/oe_CosTransactions.hrl
+/cosTransactions/src/CosTransactions_Control.erl
+/cosTransactions/src/CosTransactions_Coordinator.erl
+/cosTransactions/src/CosTransactions_HeuristicCommit.erl
+/cosTransactions/src/CosTransactions_HeuristicHazard.erl
+/cosTransactions/src/CosTransactions_HeuristicMixed.erl
+/cosTransactions/src/CosTransactions_HeuristicRollback.erl
+/cosTransactions/src/CosTransactions_Inactive.erl
+/cosTransactions/src/CosTransactions_InvalidControl.erl
+/cosTransactions/src/CosTransactions_NoTransaction.erl
+/cosTransactions/src/CosTransactions_NotPrepared.erl
+/cosTransactions/src/CosTransactions_NotSubtransaction.erl
+/cosTransactions/src/CosTransactions_PropagationContext.erl
+/cosTransactions/src/CosTransactions_RecoveryCoordinator.erl
+/cosTransactions/src/CosTransactions_Resource.erl
+/cosTransactions/src/CosTransactions_SubtransactionAwareResource.erl
+/cosTransactions/src/CosTransactions_SubtransactionsUnavailable.erl
+/cosTransactions/src/CosTransactions_SynchronizationUnavailable.erl
+/cosTransactions/src/CosTransactions_Terminator.erl
+/cosTransactions/src/CosTransactions_TransIdentity.erl
+/cosTransactions/src/CosTransactions_TransactionFactory.erl
+/cosTransactions/src/CosTransactions_Unavailable.erl
+/cosTransactions/src/CosTransactions_WrongTransaction.erl
+/cosTransactions/src/CosTransactions_otid_t.erl
+/cosTransactions/src/ETraP_Server.erl
+/cosTransactions/src/oe_CosTransactions.erl
+/orber/COSS/CosNaming/CosNaming.hrl
+/orber/COSS/CosNaming/CosNaming_Binding.erl
+/orber/COSS/CosNaming/CosNaming_BindingIterator.erl
+/orber/COSS/CosNaming/CosNaming_BindingIterator.hrl
+/orber/COSS/CosNaming/CosNaming_BindingList.erl
+/orber/COSS/CosNaming/CosNaming_Name.erl
+/orber/COSS/CosNaming/CosNaming_NameComponent.erl
+/orber/COSS/CosNaming/CosNaming_NamingContext.erl
+/orber/COSS/CosNaming/CosNaming_NamingContext.hrl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt.erl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt.hrl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt_AlreadyBound.erl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt_CannotProceed.erl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt_InvalidAddress.erl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt_InvalidName.erl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt_NotEmpty.erl
+/orber/COSS/CosNaming/CosNaming_NamingContextExt_NotFound.erl
+/orber/COSS/CosNaming/CosNaming_NamingContext_AlreadyBound.erl
+/orber/COSS/CosNaming/CosNaming_NamingContext_CannotProceed.erl
+/orber/COSS/CosNaming/CosNaming_NamingContext_InvalidName.erl
+/orber/COSS/CosNaming/CosNaming_NamingContext_NotEmpty.erl
+/orber/COSS/CosNaming/CosNaming_NamingContext_NotFound.erl
+/orber/COSS/CosNaming/oe_cos_naming.erl
+/orber/COSS/CosNaming/oe_cos_naming.hrl
+/orber/COSS/CosNaming/oe_cos_naming_ext.erl
+/orber/COSS/CosNaming/oe_cos_naming_ext.hrl
+/orber/examples/Stack/StackModule.hrl
+/orber/examples/Stack/StackModule_EmptyStack.erl
+/orber/examples/Stack/StackModule_Stack.erl
+/orber/examples/Stack/StackModule_Stack.hrl
+/orber/examples/Stack/StackModule_StackFactory.erl
+/orber/examples/Stack/StackModule_StackFactory.hrl
+/orber/examples/Stack/oe_stack.erl
+/orber/examples/Stack/oe_stack.hrl
+/orber/src/CORBA.hrl
+/orber/src/OrberApp.hrl
+/orber/src/OrberApp_IFR.erl
+/orber/src/OrberApp_IFR.hrl
+/orber/src/erlang.hrl
+/orber/src/erlang_binary.erl
+/orber/src/erlang_pid.erl
+/orber/src/erlang_port.erl
+/orber/src/erlang_ref.erl
+/orber/src/oe_CORBA.erl
+/orber/src/oe_CORBA.hrl
+/orber/src/oe_OrberIFR.erl
+/orber/src/oe_OrberIFR.hrl
+/orber/src/oe_erlang.erl
+/orber/src/oe_erlang.hrl
diff --git a/lib/asn1/doc/src/Makefile b/lib/asn1/doc/src/Makefile
index be8755f0ff..d29225f6c9 100644
--- a/lib/asn1/doc/src/Makefile
+++ b/lib/asn1/doc/src/Makefile
@@ -51,9 +51,7 @@ XML_REF3_FILES = asn1ct.xml \
GEN_XML = \
asn1_spec.xml
-XML_PART_FILES = \
- part.xml \
- part_notes.xml
+XML_PART_FILES = part.xml
XML_HTML_FILE = \
notes_history.xml
diff --git a/lib/asn1/doc/src/note.gif b/lib/asn1/doc/src/note.gif
deleted file mode 100644
index 6fffe30419..0000000000
--- a/lib/asn1/doc/src/note.gif
+++ /dev/null
Binary files differ
diff --git a/lib/asn1/doc/src/notes_history.xml b/lib/asn1/doc/src/notes_history.xml
deleted file mode 100644
index e6c423e79e..0000000000
--- a/lib/asn1/doc/src/notes_history.xml
+++ /dev/null
@@ -1,1782 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2006</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>ASN1 Release Notes</title>
- <prepared>Bertil Karlsson</prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date>06-04-24</date>
- <rev></rev>
- <file>notes_history.sgml</file>
- </header>
- <p>This document describes the changes made to the asn1 system
- from version to version. The intention of this document is to
- list all incompatibilities as well as all enhancements and
- bug-fixes for every release of the asn1 application. Each release of asn1
- thus constitutes one section in this document. The title of each
- section is the version number of asn1.</p>
-
-
- <section>
- <title>Asn1 1.4.4.14</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Data in info/0 in generated code is moved to attribute
- asn1_info, thus vsn value remains the same if compiler
- options for asn1-spec differs but the generated code is
- the same.</p>
- <p>Own Id: OTP-6462</p>
- </item>
- <item>
- <p>Dialyzer warnings on asn1 are removed, i.e. dead code
- removed.</p>
- <p>Own Id: OTP-6506</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.13</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Now it is possible to use 'asn1config' and 'inline'
- options together. It is also possible to use 'inline' on
- a single file like:
- <c>asn1ct:compile("MyASN1spec.asn",[inline])</c>.</p>
- <p>Own Id: OTP-6405</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.12</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>As a complement to the option "{inline,OutputFile}" it is
- now possible to use the option "inline". Then asn1 creates
- an output file with the name of the source .set file.</p>
- <p>Own Id: OTP-6314</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.11</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When compiling an asn1 source that reference a type in
- another source the compiler uses the asn1db file of the
- other source to resolve the reference. It also tests
- whether the other source has been updated since the
- asn1db file was generated. This last test was to brutal
- in that it exits compilation when no source was found,
- even though a asn1db file existed. Changed behavior from
- a brutal exit to a warning.</p>
- <p>Own Id: OTP-6143</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.10</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>asn1 encoding failed on BIT STRING with constraint
- <c>(SIZE (32..MAX))</c>.</p>
- <p>Own Id: OTP-5932</p>
- </item>
- <item>
- <p>Race condition removed in server for variable names for
- generated code.</p>
- <p>Own Id: OTP-6111</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.9</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Now exists a default function clause for table lookup of
- a table constraint. This causes a nice error instead of a
- crash. Did also remove some obsolete funs ({Mod,Fun}) in
- generated code.</p>
- <p>Own Id: OTP-5783</p>
- </item>
- <item>
- <p>ASN1-compiler failed to derive a value out of an external
- reference in some certain cases, when compiling specs so
- that the spec with the reference was compiled before the
- spec with the defined value.</p>
- <p>Own Id: OTP-5812 Aux Id: seq10133 </p>
- </item>
- <item>
- <p>The documentation of how records of embedded types are
- named is extended and made clearer by examples and rules.
- The section "Naming of Records in .hrl Files" in the
- User's Guide is added.</p>
- <p>Own Id: OTP-5831 Aux Id: seq10133 </p>
- </item>
- <item>
- <p>The compiler failed to give right name to record/function
- of a parameterized type that was referenced through
- another instance of a parameterized type in another
- module. The fault occurred when modules were compiled in a
- certain order. Now the compiler resolves the name
- correctly.</p>
- <p>Own Id: OTP-5832 Aux Id: seq10133 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.8</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The dynamic sort of SET OF values now correctly handles
- values encoded in the "ber_bin, der, optimize" mode, the
- value of a SET OF is a list of binaries.</p>
- <p>Own Id: OTP-5687</p>
- </item>
- <item>
- <p>Bad code was generated for an INTEGER with value-range. If
- the value that was encoded had a lower bound with
- negative value it caused a crash. This bug is now
- removed.</p>
- <p>Own Id: OTP-5688 Aux Id: seq10049 </p>
- </item>
- <item>
- <p>Compiler now handles wrong include paths by returning an
- error if a referenced module is not available.</p>
- <p>Own Id: OTP-5689</p>
- </item>
- <item>
- <p>The bug causing a runtime error when encoding a type
- defined by: <c>BIT STRING {a(1),b(2)}</c> with the value
- [] in <c>per_bin</c> mode is now removed.</p>
- <p>Own Id: OTP-5710 Aux Id: seq10066 </p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Better handling of filename paths</p>
- <p>Own Id: OTP-5701</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.7</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Effective constraint for <c>per</c> now corrected. For
- instance <c>INTEGER (0|15..269)</c> didn't work properly.</p>
- <p>Own Id: OTP-5477 Aux Id: OTP-5511 </p>
- </item>
- <item>
- <p>Adjusted compiler so that functions in generated code
- only are exported once.</p>
- <p>Own Id: OTP-5509</p>
- </item>
- <item>
- <p>Fixed the compiler failure when handling a value range
- constraint with an extension mark that had the Lower
- bound and/or Upper bound values as an external reference
- to a defined value.</p>
- <p>Own Id: OTP-5511 Aux Id: OTP-5466 </p>
- </item>
- <item>
- <p>Removed sorting of elements for SEQUENCE OF. It shall
- only be done in SET OF.</p>
- <p>Own Id: OTP-5602</p>
- </item>
- <item>
- <p>Corrected code that generated code causing badarith
- warning.</p>
- <p>Own Id: OTP-5616</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.6</title>
-
- <section>
- <title>Known Bugs and Problems</title>
- <list type="bulleted">
- <item>
- <p>Compiler now correctly crashes when compiling bad values.
- Failed for instance on INTEGER value that was a reference
- to a defined value. Also solved problem with a union
- constraint on an INTEGER.</p>
- <p>Own Id: OTP-5457</p>
- </item>
- <item>
- <p>Additional coverage of object set syntax.</p>
- <p>Own Id: OTP-5466</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug due to representation of open_type values is now
- fixed. It could cause problem if one used the EXTERNAL
- type.</p>
- <p>Own Id: OTP-5302</p>
- </item>
- <item>
- <p>Due to an internal error the same code could have been
- generated more than one time. This happened for the
- exclusive decode functionality.</p>
- <p>Own Id: OTP-5378</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.4</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Empty objects caused problems. There was trouble when an
- object set referenced imported objects that in turn
- referenced imported types. Lacked support of
- SelectionType in object. All these have been attended.</p>
- <p>Own Id: OTP-5240</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Now it is possible to inline asn1 run-time functionality
- in the module generated by the asn1 compiler. Thus, it
- will be only one module doing all encoding/decoding.</p>
- <p>Own Id: OTP-5243</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.3</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A class that was referenced in two steps caused a
- compiler failure. It is now corrected.</p>
- <p>Own Id: OTP-5103</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>Optionally make it possible to get the un-decoded rest along with
- the return value. Compile with option <em>undec_rest</em>.</p>
- <p>Own Id: OTP-5104</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.2</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>An error due to unchecked referenced imported type resulted
- in missing tag in some table constraint cases. This error is
- now corrected. Error occurred during decode in
- <c>ber_bin optimized</c> version.</p>
- <p>Own Id: OTP-5022</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4.1</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When a referenced value in another module in turn referenced a
- defined value the compilation crashed. This is due to the new
- routines for compilation, that external references are resolved
- during compilation, and not by the order in which modules are
- compiled. This error is now corrected.</p>
- <p>Own Id: OTP-4970</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.4</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Functionality for parameterized class is added. Parsing failures on
- WithSyntax spec is corrected.</p>
- <p>Own Id: OTP-4893</p>
- </item>
- <item>
- <p>The failure due to Parameterized Type when parameter is an object
- set is corrected.</p>
- <p>Own Id: OTP-4894</p>
- <p>Aux Id: OTP-4893</p>
- </item>
- <item>
- <p>Object Identifier values with two components and the first was a
- value reference failed due to parsing conflicts. Now it is
- corrected.</p>
- <p>Own Id: OTP-4895</p>
- </item>
- <item>
- <p>The erroneous comparison of file name and asn1 module name could
- cause compilation failure. The situation for this failure is rare,
- it requires that other processes modifies the compiled file during
- the compilation procedure. It is now fixed.</p>
- <p>Own Id: OTP-4944</p>
- <p>Aux Id: seq8429</p>
- </item>
- <item>
- <p>Selective decode was ignored when exclusive decode spec in asn1
- configfile was missing. Selective decode failed when the selected
- type was the top type. These bugs are now removed.</p>
- <p>Own Id: OTP-4953</p>
- <p>Aux Id: seq8436</p>
- </item>
- <item>
- <p>The test interface asn1ct:test/1,2,3 and asn1ct:value/2 failed for
- open type and EXTERNAL. The bug is now removed.</p>
- <p>Own Id: OTP-4955</p>
- <p>Aux Id: seq8438)</p>
- </item>
- <item>
- <p>Two equal functions were generated for two components referencing
- the same type when they were picked by the action "parts". The bug
- is now fixed.</p>
- <p>Own Id: OTP-4957</p>
- <p>Aux Id: seq8434</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>INTEGER with named number list and ENUMERATED can now be sub
- constrained with names from the names list.</p>
- <p>Own Id: OTP-4917</p>
- </item>
- <item>
- <p>Now there is support for SelectionType (X 680 section 29)</p>
- <p>Own Id: OTP-4918</p>
- </item>
- <item>
- <p>The compiler now resolves circular dependencies. When asn1 specs
- IMPORTS from each other so that there are circular dependencies.</p>
- <p>Own Id: OTP-4919</p>
- </item>
- <item>
- <p>Now is the asn1 type UTF8String supported. For user instructions
- see documentation.</p>
- <p>Own Id: OTP-4965</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.3.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The <c>{internal_error,...,{ unrecognized_type,...}}</c>
- error occurring for a SET type when compiling with options
- <c>[ber_bin,optimize,der]</c> is now corrected.</p>
- <p>Own Id: OTP-4866</p>
- </item>
- <item>
- <p>False encode of BIT STRING in PER (per_bin,optimize) is fixed. The error occurred when there was a type like BIT STRING (SIZE(C)) and C &gt; 16.</p>
- <p>Own Id: OTP-4869</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.3</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Functionality to handle parameterized object sets have been added.</p>
- <p>Own Id: OTP-4832</p>
- </item>
- <item>
- <p>Bug causing duplicated function definitions using exclusive decode is removed.</p>
- <p>Own Id: OTP-4833)</p>
- </item>
- <item>
- <p>The race condition when loading asn1 driver is solved.</p>
- <p>Own Id: OTP-4835</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>A specialized decode, <em>selective decode</em> is now available. It decodes a chosen internal sub-type of a constructed type.</p>
- <p>Own Id: OTP-4856)</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.2.2</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Release of Asn1 1.4.2.1 on R7B, The functionality is the same, but
- the layer between the driver and the asn1 erlang code is different.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.2.1</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>ObjectDescriptor does now work as part of a sequence, set or choice.</p>
- <p>Own Id: OTP-4773</p>
- </item>
- <item>
- <p>When a SEQUENCE that have extension mark was decoded inside a
- SEQUENCE OF it could cause decode error due to a failure in
- restbytes2. It is now corrected.</p>
- <p>Own Id: OTP-4791)</p>
- </item>
- <item>
- <p>Now the bug is fixed that caused the compiler crash on an untagged
- optional open type.</p>
- <p>Own Id: OTP-4792</p>
- </item>
- <item>
- <p>The earlier exit caused by bad in-data is now fixed so it will
- return an {error,Reason} tuple.</p>
- return an {error,Reason} tuple.</p>
- <p>Own Id: OTP-4797</p>
- </item>
- <item>
- <p>Open type encoded with indefinite length is now correct decoded.</p>
- <p>Own Id: OTP-4798</p>
- </item>
- <item>
- <p>Now is absent optional open types handled correctly.</p>
- <p>Own Id: OTP-4799</p>
- </item>
- <item>
- <p>Now is the necessary functions available for sorting in run-time of
- SET and SET OF components.</p>
- <p>Own Id: OTP-4809</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.2</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When a component in a SEQUENCE is a CHOICE (or reference to a CHOICE)
- and the SEQUENCE's component and one of the alternatives in the CHOICE
- have identical names, an error may occur if one doesn't use the
- 'optimized' versions of the compiler. In the older versions (<c>ber, ber_bin, per, per_bin</c>) one could optionally apply a value of a
- component as <c>{ComponentName,Value}</c>, and the generated code
- chooses the second element of the tuple. However, a value of a CHOICE
- must be applied as a tuple: <c>{AlternativeName,Value}</c>. Thus,
- in the rare case described above and if the value to the SEQUENCE's
- component is not in a tuple notation the
- <c>{AlternativeName,Value}</c> will be peeled off in the SEQUENCE
- and the value fed to the CHOICE will only be the <c>Value</c>
- part of <c>{AlternativeName,Value}</c>, and the encoder crashes.
- The best way to avoid this is to use the optimized version of the
- compiler where the unnecessary tuple notation
- <c>{ComponentName,Value}</c> no longer is allowed. Since it isn't
- possible to solve this bug in the compiler.</p>
- <p>Own Id: OTP-4693</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>Exclusive decode is enabled by a compiler option and a configuration
- file. It makes it possible to leave parts of an ASN.1 encoded message
- un-decoded.</p>
- <p>Own Id: OTP-4744</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.1.1</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The documentation about how extensibility is handled is now corrected.</p>
- <p>Own Id: OTP-4663</p>
- </item>
- <item>
- <p>Function in object now calls the exported function</p>
- <p>Own Id: OTP-4665</p>
- </item>
- <item>
- <p>Now is tags for ObjectClassFieldType analyzed correctly.</p>
- <p>Own Id: OTP-4666</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4.1</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Now is the Default value for an ENUMERATED returned as the name from
- the NamedList when decoding.</p>
- <p>Own Id: OTP-4633</p>
- </item>
- <item>
- <p>It was an internal failure when permitted alphabet constraint existed
- together with for instance a size constraint. E.g. when a
- referenced type is constrained by a size constraint and the defined
- type in turn is constrained by a permitted alphabet constraint.</p>
- <p>Own Id: OTP-4559</p>
- </item>
- <item>
- <p>Record is generated in hrl file for a CHOICE with extension mark
- that has an internal SEQUENCE/SET definition.</p>
- <p>Own Id: OTP-4560</p>
- </item>
- <item>
- <p>Now is the length of a SEQUENCE/SET OF correctly encoded/decoded (PER).</p>
- <p>Own Id: OTP-4590</p>
- </item>
- <item>
- <p>The problem with unordered decoded terms when a component is a
- ObjectClassFieldType has been solved.</p>
- <p>Own Id: OTP-4591</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>More complex definitions with TableConstraints where the SimpleTable
- and ComponentRelation are on different levels is now fully
- supported.</p>
- <p>Own Id: OTP-4631</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.4</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>Each generated .erl file have now a function info/0 that returns
- information about the used compiler version and options.</p>
- <p>Own Id: OTP-4373</p>
- </item>
- <item>
- <p>When compiling an ASN.1 module the compiler generates an Erlang module
- that is compiled by the Erlang compiler. Earlier it was not possible to
- add options to the final step, the Erlang compilation. By adding any
- option that is not recognized as a specific ASN.1 option it will be
- passed to the final step like: <c>erlc +debug_info Mymodule.asn</c> or
- <c>asn1ct:compile('Mymodule',[debug_info])</c>.</p>
- <p>Own Id: OTP-4491</p>
- </item>
- <item>
- <p>Earlier one couldn't multi file compile modules that had different
- tagdefault, which now is possible. Equal Type/Value names in different
- modules are resolved by renaming (concatenate type name and module
- name): If two types with the same name T exist in module A and module B
- they will get the new names TA and TB.</p>
- <p>(Own Id: OTP-4492)</p>
- <p>Aux Id: OTP-3983</p>
- </item>
- <item>
- <p>BER: Encode/decode of data have been significantly improved. By use of
- the compiler options <c>ber_bin</c> and <c>optimize</c>,
- optimized code will be generated and the optimized run-time module will
- be used.</p>
- <p>Own Id: OTP-4493</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.3.3.1</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Proper length encoding and padding implemented for a <c>BIT STRING</c> with
- NamedNumberList and size constraint as value range. This functionality
- didn't work in the rare occasion when the NamedNumberList is shorter
- than the lower bound of the constraint.As in this example:
- <c>TestS ::= BIT STRING {a (0),b (1)} (SIZE (3..8))</c></p>
- <p>(Own Id: OTP-4353)</p>
- </item>
- <item>
- <p>Bug in compiler, when an <c>OBJECT IDENTIFIER</c> value consisting of
- two identifiers (Defined values or Name form identifiers) was falsely
- interpreted causing a compiling error is now corrected.</p>
- <p>(Own Id: OTP-4354)</p>
- </item>
- <item>
- <p>Internal error in check phase that caused crash on
- <c>ObjectClassFieldType</c> in ber_bin is corrected.</p>
- <p>(Own Id: OTP-4390)</p>
- </item>
- <item>
- <p>Tags for open types are handled according to <c>x.680 30.6c</c>, i.e.
- open types shall not be tagged <c>IMPLICIT.</c></p>
- <p>(Own Id: OTP-4395)</p>
- <p>(Aux Id: OTP-4390)</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.3.3</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Now gives the compiler an appropriate error report when exported
- undefined types are detected.</p>
- <p>(Own Id: OTP-4129)</p>
- </item>
- <item>
- <p>The type <c>ObjectDescriptor</c> is now supported, previously the
- implementation of encode/decode for this rarely used type was
- incomplete.</p>
- <p>(Own Id: OTP-4161)</p>
- <p>(Aux Id: seq7165)</p>
- </item>
- <item>
- <p>In case of per and compact_bit_string the rightmost byte were erroneous
- truncated when the rightmost bits of that byte were zeros. This is now
- corrected.</p>
- <p>(Own Id: OTP-4200)</p>
- </item>
- <item>
- <p>Bad match of return-value from decode_length in skipvalue/3 has now been
- fixed.</p>
- <p>(Own Id: OTP-4232)</p>
- </item>
- <item>
- <p>Now is decode of ENUMERATED handled correctly, when tagged EXPLICIT.</p>
- <p>(Own Id: OTP-4234)</p>
- </item>
- <item>
- <p>The compiler now parses and handles the ValueFromObject construct.</p>
- <p>(Own Id: OTP-4242)</p>
- </item>
- <item>
- <p>Now does the compiler handle the case when the object set in simple
- table and componentrelation constraints is of a CLASS without a UNIQUE
- field. In this case is the octets, which is assumed to be encoded,
- encoded as an open type.</p>
- <p>(Own Id: OTP-4248)</p>
- <p>(Aux Id: OTP-4242)</p>
- </item>
- <item>
- <p>Compiler handles objects in AdditionalElementSetSpec in ObjectSetSpec,
- i.e. the objects that are referred to after the ellipses in an object set.</p>
- <p>(Own Id: OTP-4275)</p>
- </item>
- <item>
- <p>Now are values with a component of type CHOICE encoded with indefinite
- length correctly decoded.</p>
- <p>(Own Id: OTP-4358)</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>The language constructs (from the old 1988 standard) <c>ANY</c>
- and <c>ANY DEFINED BY</c> are now implemented.</p>
- <p>(Own Id: OTP-2741)</p>
- <p>(Aux Id: seq 1188)</p>
- </item>
- <item>
- <p>Now it is checked in run-time if a <c>OBJECT IDENTIFIER</c> value is invalid</p>
- <p>(Own Id: OTP-4235)</p>
- </item>
- <item>
- <p>The ASN.1 types EXTERNAL,EMBEDDED PDV and CHARACTER STRING now have full support in the compiler.</p>
- <p>(Own Id: OTP-4247)</p>
- </item>
- <item>
- <p>A driver in C does the final job (complete) of the PER encoding when
- files are compiled with <c>per_bin</c> and <c>optimize</c> flags.
- It gives significant faster encoding for PER.</p>
- <p>(Own Id: OTP-4355)</p>
- </item>
- <item>
- <p>Encode and decode of PER encoding has been made faster by moving
- analysis done in run-time to compile-time. These optimizations are
- available by compiling ASN.1 files with options <c>per_bin</c> and
- <c>optimize</c>.</p>
- <p>(Own Id: OTP-4381)</p>
- <p>(Aux Id: OTP-4355)</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.3.2</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Now does the compiler check values (including referenced values), and
- formats the value so it is suitable to use as input to encoding
- functions.</p>
- <p>(Own Id: OTP-3277)</p>
- <p>(Aux Id: OTP-4103)</p>
- </item>
- <item>
- <p>Unnecessary external function calls in generated code are now generated
- as internal function calls.</p>
- <p>(Own Id: OTP-4073)</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>Now is Information Objects supported in BER encoding.</p>
- <p>(Own Id: OTP-3980)</p>
- <p>(Aux Id: OTP-3979 OTP-3978)</p>
- <p></p>
- </item>
- <item>
- <p>PER: A new option <c>per_bin</c> is now supported. When used the
- generated encode/decode functions use binaries and the bit syntax to
- get better performance than the old <c>per</c> variant which used
- lists. All values input to encode and returned from decode are
- compatible between <c>per</c> and <c>per_bin</c> except for
- open types which are represented as binaries with per_bin and octet
- lists with per. We recommend that you use per_bin instead of per from
- now on, the use of binaries will be the default in coming versions and
- all improvements and optimizations for PER will be concentrated to that
- solution.</p>
- <p>(Own Id: OTP-4094)</p>
- <p></p>
- </item>
- <item>
- <p>Support for DER implemented. Used by flag +der when compiling. Include
- the full BER encoding plus: sorting of SET components, sorting of
- encoded elements in SET OF, full check of default values in SET and
- SEQUENCE. See new documentation on DER in user_guide sections 1.3.1;
- 1.4.11; 1.4.12; 1.4.14; 1.4.16 and 1.10, in the reference manual for
- asn1ct.</p>
- <p>(Own Id: OTP-4103)</p>
- <p></p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.3.1</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Do not generate record in .hrl file for SET types</p>
- <p>Own Id: OTP-4025</p>
- </item>
- <item>
- <p>Fixed internal error when using BIT STRINGs with Named Number List in combination with <c>compact_bit_string</c> and <c>ber_bin</c> options.</p>
- <p>Own Id: OTP-4026</p>
- <p>Aux Id: OTP-3982</p>
- </item>
- <item>
- <p>The atom 'com' can now be used in ENUMERATED as an EnumerationItem.</p>
- <p>Own Id: OTP-4037</p>
- <p>Aux Id: Seq 7036</p>
- </item>
- <item>
- <p>ber: Now it is possible (again) to encode data format "{Type,Value}" in a SEQUENCE OF RequestParameter, when RequestParameter is of type ENUMERATED. The {Type,Value}
- notation is not recommended for use, it is redundant and exist only for very ancient backwards compatibility reasons. The "feature" might be removed in forthcoming versions.</p>
- <p>Own Id: OTP-4057</p>
- <p>Aux Id: Seq 7066</p>
- </item>
- <item>
- <p>A bug in the parser, that caused failure on COMPONENTS OF is now removed.</p>
- <p>Own Id: OTP-4058</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.3</title>
-
- <section>
- <title>Known problems</title>
- <list type="bulleted">
- <item>
- <p>The compiler will now check that a value referenced by name
- does exist.</p>
- <p>Own Id: OTP-3277</p>
- </item>
- <item>
- <p>BER:Decode of a type T ::= SEQUENCE OF C fails if C is encoded with indefinite length.
- This is know corrected.</p>
- <p>Own Id: OTP-3811</p>
- <p>Aux Id: seq5040</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The new parser handles imports when one import ends with FROM, a modulename and a reference to a objectidentifier followed by imports from other modules.</p>
- <p>Own Id: OTP-3463</p>
- </item>
- <item>
- <p>The compiler did not check that a name mentioned as EXPORTED
- actually is defined within the module.
- This is now corrected.</p>
- <p>Own Id: OTP-3659</p>
- </item>
- <item>
- <p>Removed bug caused by use of nested indefinite length</p>
- <p>Own Id: OTP-3994</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>Now supporting most common use of parameterization according to X.683</p>
- <p>(Own Id: OTP-3978)</p>
- </item>
- <item>
- <p>PER: Now supporting most common use of Information Objects according to X.681. A new parser has been implemented. The error messages due to syntax errors are slightly different than previous. TableConstraint part of X.682 now also supported.</p>
- <p>Own Id: OTP-3979</p>
- </item>
- <item>
- <p>New compiler option added: <c>ber_bin</c>. The compiler generates code with new bit syntax. Run time functions uses bit syntax when feasible. Higher encoding/decoding performance in most cases. Se also comments for Asn1 1.2.9.3.</p>
- <p>Own Id: OTP-3981</p>
- </item>
- <item>
- <p>A more compact format of BIT STRING in Erlang is now available by use of the compiler option <c>compact_bit_string</c>. It is much faster when large BIT STRINGs are used.</p>
- <p>Own Id: OTP-3982</p>
- </item>
- <item>
- <p>Now possible to merge many ASN.1 input files to one Erlang file by use of a configuration file that lists the ASN.1 files.</p>
- <p>Own Id: OTP-3983</p>
- </item>
- <item>
- <p>New documentation in <em>User's Guide</em> in section:</p>
- <p>3.1: New compile-time functions and options are described.</p>
- <p>4.6: New compact format of BIT STRING is described.</p>
- <p>4.8: Additional comments on character strings.</p>
- <p>7: New section describing ASN.1 Information Objects.</p>
- <p>8: New section describing Parameterization.</p>
- <p><em>Reference Manual/asn1ct</em> New compile options are described.</p>
- <p>Own Id: OTP-3984</p>
- <p>Aux Id: OTP-3978, OTP-3979, OTP-3981, OTP-3982, OTP-3983</p>
- </item>
- <item>
- <p>Added the functionality to invoke ASN1Mod:encode (and decode).</p>
- <p>Own Id: OTP-3985</p>
- </item>
- <item>
- <p>Performance improvements by removing not necessary use of apply when calling asn1rt:encode. Also other general improvements.</p>
- <p>Own Id: OTP-3988</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.2.9.6</title>
-
- <section>
- <title>Known problems</title>
- <list type="bulleted">
- <item>
- <p>The compiler does not check that an exported name actually exists in the ASN.1 module.</p>
- <p>Own Id: OTP-3659</p>
- </item>
- <item>
- <p>The compiler does not check that a value referenced by name does exist.</p>
- <p>Own Id: OTP-3277</p>
- </item>
- <item>
- <p>BER: The compiler does not take the extensions into account when checking if
- the tags are unique in a SEQUENCE or SET.</p>
- <p>Own Id: OTP-3304</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>PER: Trailing zeroes in a BIT STRING declared without named bits
- should not be removed in the encodings.</p>
- <p>Own Id: OTP-3830</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.2.9.5</title>
-
- <section>
- <title>Known problems</title>
- <p>Same as for 1.2.9.3.</p>
- </section>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>PER: Constraints are not propagated when types are
- referring to each other. Example:</p>
- <code type="none">
-
- TBCD-STRING ::= OCTET STRING
-
- LAI ::= TBCD-STRING (SIZE(3)) </code>
- <p>The size constraint is not passed on during encode,decode
- resulting in wrong encoding for PER , it is
- coded with a length determinant which should not be there
- when the length is fixed. For BER this does not matter because the constraints does
- not affect the encodings.</p>
- <p>Own Id: OTP-3713</p>
- </item>
- <item>
- <p>The generated code gets wrong if there are several ENUMERATED fields in a SEQUENCE or SET, this is now corrected.</p>
- <p>Own Id: OTP-3796</p>
- </item>
- <item>
- <p>BER:Decode of a type T ::= SEQUENCE OF C fails if C is encoded with indefinite length.
- This is know corrected.</p>
- <p>Own Id: OTP-3811</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.2.9.3</title>
-
- <section>
- <title>Known problems</title>
- <list type="bulleted">
- <item>
- <p>The compiler does not check that an exported name actually exists in the ASN.1 module.</p>
- <p>Own Id: OTP-3659</p>
- </item>
- <item>
- <p>The compiler does not check that a value referenced by name does exist.</p>
- <p>Own Id: OTP-3277</p>
- </item>
- <item>
- <p>BER: The compiler does not take the extensions into account when checking if
- the tags are unique in a SEQUENCE or SET.</p>
- <p>Own Id: OTP-3304</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>This version supports soft upgrade from versions 1.2.6 1.2.7.</p>
- </item>
- <item>
- <p>In an ENUMERATED type like this:</p>
- <code type="none">
-\011\011T ::= ENUMERATED { blue, green} </code>
- <p>The symbols was encoded/decoded with the wrong values, i.e in
- reverse order. This is now corrected.</p>
- <p>Own Id: OTP-3700</p>
- </item>
- <item>
- <p>PER: OCTET STRING with Size constrained to a single value i.e fixed size
- was treated wrong during encode and decode. This is now corrected.</p>
- <p>Own Id: OTP-3701</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>There is now a new compiler option <c>ber_bin</c> available that can be used to
- generate encode/decode functions for BER that uses the new "bit-syntax" to
- make the functions more efficient. The <c>ber_bin</c> option is used
- as an alternative to the <c>ber</c> and <c>per</c> options.</p>
- <p>The encode function then produces a
- possibly nested list of binaries and integer lists. The decode function does
- in this case require a single binary as input instead of a list.
- The modules generated with this option require that you have an R7A or later
- system, otherwise they will not compile and the runtime module asn1rt_ber_bin
- can not be executed.</p>
- <p>The ber_bin option is not officially supported in this version (will be
- in a later version) but is provided for those who want to try it.
- It should be significantly faster at decode and is slightly faster at encode.
- Exactly how performance differs between this binary approach and the
- list approach depends highly on the type of input.
- Another thing worth noting is that both approaches still have a lot of
- solutions in common which can be improved a lot to gain even better
- performance.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.2.9.2</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>BER: Encode/decode of extension components did not work properly. This is now corrected.</p>
- <p>Own Id: OTP-3395</p>
- <p>Aux Id: </p>
- <p>PER:The encode/decode of NULL as an open type has been corrected. An open type must always have a length of at least 1 byte even if the contained
- value (e.g NULL) encodes to nothing.</p>
- <p>Own Id: OTP-3496</p>
- <p>Aux Id: </p>
- </item>
- <item>
- <p>BER:In the current implementation extension components of a SEQUENCE are required
- to be present when they are specified as mandatory. This is an error, all extension
- components are "optional" even if they are not specified to have the OPTIONAL or
- DEFAULT property. This is now corrected.</p>
- <p>Own Id: OTP-3278</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>The ASN.1 language feature <c>COMPONENTS OF</c> is now implemented.</p>
- <p>Own Id: OTP-2515</p>
- </item>
- <item>
- <p>The encoding and decoding of ENUMERATED and
- INTEGER with NamedNumbers is made more efficient and thus
- faster in runtime.</p>
- <p>Own Id: OTP-3464</p>
- <p>Aux Id:</p>
- </item>
- <item>
- <p>Added support for encode/decode of open type which is
- constrained to a specific type. Previously the value of
- an open type had to be a list of octets, but now the Erlang
- representation of the specific type used in the constraint
- is used both as input to encode and as output from decode.</p>
- <p>Own Id: OTP-3569</p>
- <p>Aux Id: </p>
- </item>
- <item>
- <p>PER: GeneralString, GraphicalString etc. i.e all strings
- that are not so called "known-multiplier character
- string types" are now supported by the runtime
- encode/decode functions.</p>
- <p>Own Id: OTP-3573</p>
- <p>Aux Id:</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.2.6</title>
-
- <section>
- <title>Known problems</title>
- <list type="bulleted">
- <item>
- <p>The ASN.1 language feature <c>COMPONENTS OF</c> is not implemented.</p>
- <p>Own Id: OTP-2515</p>
- </item>
- <item>
- <p>The compiler does not check that a value referenced by name does exist.</p>
- <p>Own Id: OTP-3277</p>
- </item>
- <item>
- <p>BER:In the current implementation extension components of a SEQUENCE are required
- to be present when they are specified as mandatory. This is an error, all extension
- components are "optional" even if they are not specified to have the OPTIONAL or
- DEFAULT property.</p>
- <p>Own Id: OTP-3278</p>
- </item>
- <item>
- <p>BER: The compiler does not take the extensions into account when checking if
- the tags are unique in a SEQUENCE or SET.</p>
- <p>Own Id: OTP-3304</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>This version supports soft upgrade from versions 1.1.1, 1.1.5 and 1.1.6.
- Two new runtime modules <c>asn1rt_ber_v1</c> and
- <c>asn1rt_per_v1</c> are delivered together with the old ones. This makes
- it possible to continue running applications with modules generated with the
- previous version of the asn1 compiler while modules generated by this version
- will use the new runtime modules. Note that it is only advice-able to continue
- running old generates if they are working perfectly and have no need
- for the corrections made in this version of the asn1 application.</p>
- </item>
- <item>
- <p>BER: SEQUENCEs encoded with indefinite length was not correctly decoded.
- This in now corrected.</p>
- <p>Own Id: OTP-3352</p>
- <p>Aux Id: Seq 4100</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.2.4</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The compiler now detects multiple definitions of values and types and reports this as
- an error. Previously this was detected when the generated Erlang module was compiled.</p>
- <p>Own Id: OTP-3105</p>
- </item>
- <item>
- <p>BER: An error regarding encoding of <c>ENUMERATED</c> present in asn1-1.1.1
- is corrected. The new version 1.1.2 of asn1 containing this correction is
- delivered as a "patch".</p>
- <p>Own Id: OTP-3169</p>
- </item>
- <item>
- <p>BER: Decoding of <c>SEQUENCE OF</c> and <c>SET OF</c> with indefinite length is corrected.
- The correction was first delivered in version 1.1.2.</p>
- <p>Own Id: OTP-3170</p>
- </item>
- <item>
- <p>BER: Encoding and decoding of <c>ENUMERATED</c>
- with extensionmark
- "..." did not work (crashed with a runtime error). This
- has now been corrected. If an unknown enumerated value is
- decoded (for an extensible enumerated type)
- it is returned as <c>{asn1_enum,Value}</c> where
- <c>Value</c> is an integer. Enumerated values in this format
- are also accepted by the encoder.
- ASN.1 modules containing
- <c>ENUMERATED</c> with extensionmark should be
- recompiled with the corrected
- version of the compiler. The BER runtime functions are also
- corrected.
- Note that this correction has already been delivered as a
- bugfix for R4B (OTP-2951).</p>
- <p>Own Id: OTP-3202</p>
- <p>Aux Id: Seq3745</p>
- </item>
- <item>
- <p>BER: The primitive/constructed bit in the tag byte of an encoding
- is not correct when it comes to user defined tags.
- For example in </p>
- <code type="none">
- T ::= [2] SEQUENCE { a BOOLEAN} </code>
- <p>the tag 2 does not get the constructed bit set which it should.
- This is now corrected.</p>
- <p>Own Id: OTP-3241</p>
- </item>
- <item>
- <p>The decoder can now detect if there are unexpected bytes
- remaining when all components of a sequence are decoded.
- The decoder will then return <c>{error,{asn1{unexpected,Bytes}}}</c></p>
- <p>Own Id: OTP-3270</p>
- </item>
- <item>
- <p>Values of type <c>OBJECT IDENTIFIER</c> was sometimes returned as an Erlang list
- (ASN.1 constants) and sometimes as a tuple (from the decode functions). This is now
- changed so that <c>OBJECT IDENTIFIER</c> values always are represented as an Erlang
- tuple.</p>
- <p>Own Id: OTP-3280</p>
- </item>
- <item>
- <p>PER:The encode/decode functions could not handle integers with
- a range greater than 16#7ffffff. This limit is now removed.</p>
- <p>Own Id: OTP-3287</p>
- </item>
- <item>
- <p>PER: The encoding/decoding of the length for a SET OF/SEQUENCE OF
- was wrong if there was a size constraint. This is now corrected.</p>
- <p>Own Id: OTP-3291</p>
- </item>
- <item>
- <p>PER: Encoding of a constrained INTEGER (range &gt; 16 k) was wrong for
- the value 0. This is now corrected.</p>
- <p>Own Id: OTP-3306</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>The ASN.1 module name and the filename where the ASN.1
- specification resides must match each other (has always been the
- case). This is now checked by the compiler. The check requires that
- the names match in a case or case insensitive way depending on the
- characteristics for the current system.</p>
- <p>Own Id: OTP-1843</p>
- </item>
- <item>
- <p>PER: Encode/decode of an extension value (i.e not within the root set) for
- <c>ENUMERATED</c> did not work properly. This is now corrected.
- If an unknown enumerated value is
- decoded (for an extensible enumerated type)
- it is returned as <c>{asn1_enum,Value}</c> where
- <c>Value</c> is an integer. Enumerated values in this format
- are also accepted by the encoder (if the value is &gt;= the number of known
- extension values).</p>
- <p>Own Id: OTP-2930</p>
- </item>
- <item>
- <p>Unnecessary printouts from the compiler are removed.
- The compiler version and the compiler options are now
- printed to stdout.</p>
- <p>Own Id: OTP-3276</p>
- </item>
- <item>
- <p>In order to better suite the use of ASN.1 in embedded systems only
- the modules needed in runtime are now listed in the <c>.app</c> file.</p>
- <p>Own Id: OTP-3279</p>
- </item>
- <item>
- <p>The compiler now supports extensionmarker in constraint specifications.
- Example:</p>
- <code type="none">
-INTEGER (0..10, ...) </code>
- <p>In previous version this was reported as a syntax error.</p>
- <p>Own Id: OTP-3281</p>
- </item>
- <item>
- <p>A very limited part of ITU-T recommendation X.681
- Abstract Syntax Notation One (ASN.1): Information
- object specification is now implemented. Specifically \011
- TYPE IDENTIFIER is recognized by the compiler.</p>
- <p>Own Id: OTP-3325</p>
- </item>
- <item>
- <p>Parameterization of ASN.1 specifications (ITU-T X.683) is now
- supported to a limited extent.</p>
- <p>Own Id: OTP-3326</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.1.3.1</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>BER Encoding and decoding of <c>ENUMERATED</c>
- with extensionmark
- "..." did not work (crashed with a runtime error). This
- has now been corrected. If an unknown enumerated value is
- decoded (for an extensible enumerated type)
- it is returned as <c>{asn1_enum,Value}</c> where
- <c>Value</c> is an integer. Enumerated values in this format
- are also accepted by the encoder.
- ASN.1 modules containing
- <c>ENUMERATED</c> with extensionmark should be
- recompiled with the corrected
- version of the compiler. The BER runtime functions are also
- corrected.
- Note that this correction has already been delivered as a
- bug-fix for R4B (OTP-2951).</p>
- <p>Own Id: OTP-3202</p>
- <p>Aux Id: Seq3745</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.1.1</title>
-
- <section>
- <title>Known problems</title>
- <list type="bulleted">
- <item>
- <p>The syntactic construct <c>COMPONENTS OF</c> is not
- implemented.</p>
- <p>Own Id: OTP-2515</p>
- </item>
- <item>
- <p><c>ANY</c> and <c>ANY DEFINED BY</c> are currently not
- supported.</p>
- <p>Own Id: OTP-2741</p>
- <p>Aux Id: seq 1188</p>
- </item>
- <item>
- <p>Multiple definitions of the same Type or Value is not detected
- by the compiler. The error occurs when the generated Erlang
- module is compiled.</p>
- <p>Own Id: OTP-3105</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.1</title>
-
- <section>
- <title>Known problems</title>
- <list type="bulleted">
- <item>
- <p>The primitive/constructed bit in the tag byte of an encoding
- is not correct when it comes to user defined tags.
- For example in</p>
- <code type="none">
- T ::= [2] SEQUENCE { a BOOLEAN} </code>
- <p>the tag 2 does not get the constructed bit set which it should.
- This is now corrected.</p>
- <p>Own Id: OTP-3241</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The BER decoder failed to decode certain nested data types
- where <c>IMPLICIT</c> tags where involved.
- This is now corrected.</p>
- <p>Own Id: OTP-2719</p>
- <p>Aux Id: seq 1148</p>
- </item>
- <item>
- <p>The handling of types with extension marker "..." is corrected.
- Earlier each SEQUENCE and SET with an extension marker got an
- extra field named <c>asn1_EXT</c> in the generated record.
- This was a mistake and that field is now removed (concerns
- both BER and BER).</p>
- <p>Own Id: OTP-2724</p>
- <p>Aux Id: seq 1148, OTP-2719</p>
- </item>
- <item>
- <p>The decoder (both BER and PER) could not handle unnamed
- bits of a <c>BIT STRING</c> if the type had any
- named bits declared. This is now corrected and the unnamed
- bits are returned as <c>{bit,Pos}</c> where Pos is the bit
- position. The <c>{bit,Pos}</c> can be used as input to the
- encoder too.</p>
- <p>Own Id: OTP-2725</p>
- <p>Aux Id: seq 1148,OTP-2719,OTP-2724</p>
- </item>
- <item>
- <p>The functions <c>asn1rt:decode</c> and <c>asn1ct:decode</c>
- did not always return <c>{ok,Result}</c> or
- <c>{error,Reason}</c> as documented. This is now corrected.</p>
- <p>Own Id: OTP-2730</p>
- <p>Aux Id: seq 1158</p>
- </item>
- <item>
- <p>The compiler did not accept CHOICE types as components
- of a SEQUENCE or SET when
- the modules tag default was IMPLICIT.
- Example:</p>
- <code type="none">
-C ::= CHOICE { ......}
-A ::= SEQUENCE {
-a [1] C, -- This was not accepted
-..... </code>
- <p>This was an error
- caused by a misinterpretation of the ASN.1 standard. This
- is now corrected.</p>
- <p>Own Id: OTP-2731</p>
- <p>Aux Id: seq 1163</p>
- </item>
- <item>
- <p>When decoding a SEQUENCE A which contains an OPTIONAL component
- b which is a SEQUENCE with mandatory components, the decoder
- does not detect as an error that a mandatory component of b
- is missing. The same error could occur also in other cases
- with nested types and optional components of SEQUENCE or SET.
- This is now corrected.</p>
- <p>Own Id: OTP-2738</p>
- <p>Aux Id: seq 1183</p>
- </item>
- <item>
- <p>BER Encoding and decoding of <c>ENUMERATED</c>
- with extensionmark
- "..." did not work (crashed with a runtime error). This
- has now been corrected. If an unknown enumerated value is
- decoded (for an extensible enumerated type)
- it is returned as <c>{asn1_enum,Value}</c> where
- <c>Value</c> is an integer. Enumerated values in this format
- are also accepted by the encoder.
- ASN.1 modules containing
- <c>ENUMERATED</c> with extensionmark should be
- recompiled with the corrected
- version of the compiler. The BER runtime functions are also
- corrected.</p>
- <p>Own Id: OTP-2951</p>
- <p>Aux Id: Seq 1446 OTP-2929</p>
- </item>
- <item>
- <p>The compiler does now accept all valid value notations
- for the OBJECT IDENTIFIER type. The generated code for
- those values is also corrected.</p>
- <p>Own Id: OTP-3059</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>The code generated for BER is significantly enhanced resulting
- in less code and around 300% better performance in runtime
- for the encoding of complex ASN.1 values. The performance of
- decoding is unchanged.</p>
- <p>Own Id: OTP-2806</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Asn1 1.0.3</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The <c>asn1.app</c> file is corrected.</p>
- <p>Own Id: OTP-2640</p>
- </item>
- <item>
- <p>The encoding of integers in BER did not comply with the
- standard for all values. The values was not encoded
- in the minimum number of octets as required. This is
- now corrected in the runtime module <c>asn1rt_ber</c>.</p>
- <p>Own Id: OTP-2666</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and new features</title>
- <list type="bulleted">
- <item>
- <p>The compiler now generates explicit exports directives for
- all generated
- functions that should be exported (instead of -compile(export_all)).
- This eliminates the warnings from the Erlang compiler when
- compiling the
- generated file.</p>
- <p>Own Id: OTP-1845</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>R3B02 (Asn1 1.0.2)</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The decoding of a BER encoded SEQUENCE with optional component
- of type SEQUENCE (also with optional components) could result
- in an error or wrong result if the tags are equal.</p>
- <p>Own Id: OTP-2226</p>
- </item>
- <item>
- <p>The encoding of (PER) SEQUENCE with extensionmark was wrong.
- This is now corrected.</p>
- <p>Own Id: OTP-2349</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>R3A (Asn1 0.9)</title>
-
- <section>
- <title>Fixed errors and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The asn1 compiler now detects the use of an implicit tag before <c>CHOICE</c> as an error (in accordance with the standard)</p>
- <p>Own Id: OTP-1844</p>
- </item>
- <item>
- <p>An OPTIONAL CHOICE embedded in SEQUENCE when BER coding
- caused an error when generating decode code. This is now
- corrected.</p>
- <p>Own Id: OTP-1857</p>
- <p>Aux Id: OTP-1848</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>1 ASN1 0.8.1</title>
- <p>This is the first release of the ASN1 application. This version is
- released for beta-testing. Some functionality will be added until the
- 1.0 version is released. See the release notes for the latest version
- for the exact details about new features. A list of missing features
- and restrictions can be found in the chapter below.</p>
-
- <section>
- <title>1.1 Missing features and other restrictions</title>
- <p></p>
- <list type="bulleted">
- <item>
- <p>The encoding rules BER and PER (aligned) is supported. <em>PER (unaligned) IS NOT SUPPORTED</em>.</p>
- </item>
- <item>
- <p>NOT SUPPORTED types <c>ANY</c> and <c>ANY DEFINED BY</c>
- (is not in the standard any more).</p>
- </item>
- <item>
- <p>NOT SUPPORTED types <c>EXTERNAL</c> and <c>EMBEDDED-PDV</c>. </p>
- </item>
- <item>
- <p>NOT SUPPORTED type <c>REAL</c> (planned to be implemented). </p>
- </item>
- <item>
- <p>The code generation support for value definitions in the ASN.1 notation is very limited
- (planned to be enhanced).</p>
- </item>
- <item>
- <p>The support for constraints is limited to:</p>
- </item>
- </list>
- <list type="bulleted">
- <item>
- <p>SizeConstraint SIZE(X)</p>
- </item>
- <item>
- <p>SingleValue (1)</p>
- </item>
- <item>
- <p>ValueRange (X..Y)</p>
- </item>
- <item>
- <p>PermittedAlpabet FROM (but not for BMPString and UniversalString when generating PER).</p>
- </item>
- <item>
- <p>Complex expressions in constraints is not supported (planned to be extended).</p>
- </item>
- <item>
- <p>The current version of the compiler has very limited error checking:</p>
- </item>
- <item>
- <p>Stops at first syntax error.</p>
- </item>
- <item>
- <p>Does not stop when a reference to an undefined type is found ,
- but prints an error message. Compilation of the generated
- Erlang module will then fail.</p>
- </item>
- <item>
- <p>A whole number of other semantical controls is currently
- missing. This means that the compiler will give little
- or bad help to detect what's wrong with an ASN.1
- specification, but will mostly work very well when the
- ASN.1 specification is correct.</p>
- </item>
- </list>
- <list type="bulleted">
- <item>
- <p>The maximum INTEGER supported in this version is a
- signed 64 bit integer. This limitation is probably quite
- reasonable. (Planned to be extended).</p>
- </item>
- <item>
- <p>Only AUTOMATIC TAGS supported for PER.</p>
- </item>
- <item>
- <p>Only EXPLICIT and IMPLICIT TAGS supported for BER.</p>
- </item>
- <item>
- <p>The compiler supports decoding of BER-data with indefinite
- length but it is not possible to produce data with indefinite
- length with the encoder.</p>
- </item>
- </list>
- </section>
- </section>
-</chapter>
-
diff --git a/lib/asn1/doc/src/part_notes.xml b/lib/asn1/doc/src/part_notes.xml
deleted file mode 100644
index b0a6887aa5..0000000000
--- a/lib/asn1/doc/src/part_notes.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2004</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Asn1 Release Notes</title>
- <prepared>Ingela Anderton Andin</prepared>
- <docno></docno>
- <date>>2004-09-07</date>
- <rev></rev>
- <file>part_notes.sgml</file>
- </header>
- <description>
- <p>The <em>Asn1</em> application
- contains modules with compile-time and run-time support for ASN.1.</p>
- <p>There are also release notes for
- <url href="notes_history.html">older versions</url>.</p>
- </description>
- <xi:include href="notes.xml"/>
-</part>
-
diff --git a/lib/asn1/doc/src/warning.gif b/lib/asn1/doc/src/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/lib/asn1/doc/src/warning.gif
+++ /dev/null
Binary files differ
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index 90d25d87b2..497c4fa07b 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.erl
@@ -150,7 +150,7 @@ build_file(Code, Attr, Dict, NumLabels, NumFuncs, Abst, SourceFile, Opts) ->
%% Create IFF chunk.
Chunks = case member(slim, Opts) of
- true -> [Essentials,AttrChunk,CompileChunk,AbstChunk];
+ true -> [Essentials,AttrChunk,AbstChunk];
false -> [Essentials,LocChunk,AttrChunk,CompileChunk,AbstChunk]
end,
build_form(<<"BEAM">>, Chunks).
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index d8c201a194..dcc6ad4c7c 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.erl
@@ -123,6 +123,12 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
throw:mixed ->
failed;
+ %% There was a reference to a boolean expression
+ %% from inside a protected block (try/catch), to
+ %% a boolean expression outside.
+ throw:protected_barrier ->
+ failed;
+
%% The 'xor' operator was used. We currently don't
%% find it worthwile to translate 'xor' operators
%% (the code would be clumsy).
@@ -167,7 +173,7 @@ bopt_block(Reg, Fail, OldIs, [{block,Bl0}|Acc0], St0) ->
%% whether the optimized code is guaranteed to work in the same
%% way as the original code.
%%
-%% Throws an exception if the optmization is not safe.
+%% Throw an exception if the optimization is not safe.
%%
ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) ->
%% Here are the conditions that must be true for the
@@ -184,10 +190,10 @@ ensure_opt_safe(Bl, NewCode, OldIs, Fail, PreceedingCode, St) ->
%% by the code that follows.
%%
%% 3. Any register that is assigned a value in the optimized
- %% code must be UNUSED or KILLED in the following code.
- %% (Possible future improvement: Registers that are known
- %% to be assigned the SAME value in the original and optimized
- %% code don't need to be unused in the following code.)
+ %% code must be UNUSED or KILLED in the following code
+ %% (because the register might be assigned the wrong value,
+ %% and even if the value is right it might no longer be
+ %% assigned on *all* paths leading to its use).
InitInPreceeding = initialized_regs(PreceedingCode),
@@ -304,6 +310,8 @@ dst_regs([{set,[D],_,{bif,_,{f,_}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
dst_regs([{set,[D],_,{alloc,_,{gc_bif,_,{f,_}}}}|Is], Acc) ->
dst_regs(Is, [D|Acc]);
+dst_regs([{set,[D],_,move}|Is], Acc) ->
+ dst_regs(Is, [D|Acc]);
dst_regs([_|Is], Acc) ->
dst_regs(Is, Acc);
dst_regs([], Acc) -> ordsets:from_list(Acc).
@@ -414,11 +422,10 @@ bopt_good_args([A|As], Regs) ->
bopt_good_args([], _) -> ok.
bopt_good_arg({Tag,_}=X, Regs) when Tag =:= x; Tag =:= tmp ->
- case gb_trees:get(X, Regs) of
- any -> ok;
- _Other ->
- %%io:format("not any: ~p: ~p\n", [X,_Other]),
- throw(mixed)
+ case gb_trees:lookup(X, Regs) of
+ {value,any} -> ok;
+ {value,_} -> throw(mixed);
+ none -> throw(protected_barrier)
end;
bopt_good_arg(_, _) -> ok.
diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl
index 34609a49f2..a460d54239 100644
--- a/lib/compiler/test/andor_SUITE.erl
+++ b/lib/compiler/test/andor_SUITE.erl
@@ -20,13 +20,14 @@
-export([all/1,
t_case/1,t_and_or/1,t_andalso/1,t_orelse/1,inside/1,overlap/1,
- combined/1,in_case/1]).
+ combined/1,in_case/1,before_and_inside_if/1]).
-include("test_server.hrl").
all(suite) ->
test_lib:recompile(?MODULE),
- [t_case,t_and_or,t_andalso,t_orelse,inside,overlap,combined,in_case].
+ [t_case,t_and_or,t_andalso,t_orelse,inside,overlap,combined,in_case,
+ before_and_inside_if].
t_case(Config) when is_list(Config) ->
%% We test boolean cases almost but not quite like cases
@@ -380,6 +381,65 @@ in_case_1_guard(LenUp, LenDw, LenN, Rotation, Count) ->
false -> loop
end.
+before_and_inside_if(Config) when is_list(Config) ->
+ ?line no = before_and_inside_if([a], [b], delete),
+ ?line no = before_and_inside_if([a], [b], x),
+ ?line no = before_and_inside_if([a], [], delete),
+ ?line no = before_and_inside_if([a], [], x),
+ ?line no = before_and_inside_if([], [], delete),
+ ?line yes = before_and_inside_if([], [], x),
+ ?line yes = before_and_inside_if([], [b], delete),
+ ?line yes = before_and_inside_if([], [b], x),
+
+ ?line {ch1,ch2} = before_and_inside_if_2([a], [b], blah),
+ ?line {ch1,ch2} = before_and_inside_if_2([a], [b], xx),
+ ?line {ch1,ch2} = before_and_inside_if_2([a], [], blah),
+ ?line {ch1,ch2} = before_and_inside_if_2([a], [], xx),
+ ?line {no,no} = before_and_inside_if_2([], [b], blah),
+ ?line {no,no} = before_and_inside_if_2([], [b], xx),
+ ?line {ch1,no} = before_and_inside_if_2([], [], blah),
+ ?line {no,ch2} = before_and_inside_if_2([], [], xx),
+ ok.
+
+%% Thanks to Simon Cornish and Kostis Sagonas.
+%% Used to crash beam_bool.
+before_and_inside_if(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ if
+ %% This expression occurs in a try/catch (protected)
+ %% block, which cannot refer to variables outside of
+ %% the block that are boolean expressions.
+ Do1 =:= true;
+ Do1 =:= false, Do2 =:= false, Do3 =:= delete ->
+ no;
+ true ->
+ yes
+ end.
+
+%% Thanks to Simon Cornish.
+%% Used to generate code that would not set {y,0} on
+%% all paths before its use (and therefore fail
+%% validation by the beam_validator).
+before_and_inside_if_2(XDo1, XDo2, Do3) ->
+ Do1 = (XDo1 =/= []),
+ Do2 = (XDo2 =/= []),
+ CH1 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == blah ->
+ ch1;
+ true ->
+ no
+ end,
+ CH2 = if Do1 == true;
+ Do1 == false,Do2==false,Do3 == xx ->
+ ch2;
+ true ->
+ no
+ end,
+ {CH1,CH2}.
+
+%% Utilities.
+
check(V1, V0) ->
if V1 /= V0 ->
io:fwrite("error: ~w.\n", [V1]),
@@ -393,5 +453,3 @@ echo(X) ->
X.
id(I) -> I.
-
-
diff --git a/lib/compiler/test/compilation_SUITE_data/on_load.erl b/lib/compiler/test/compilation_SUITE_data/on_load.erl
index 92bcf74624..e9b5ec7f34 100644
--- a/lib/compiler/test/compilation_SUITE_data/on_load.erl
+++ b/lib/compiler/test/compilation_SUITE_data/on_load.erl
@@ -12,7 +12,7 @@
do_on_load() ->
local_function(),
- true.
+ ok.
local_function() ->
ok.
diff --git a/lib/cosEvent/doc/src/Makefile b/lib/cosEvent/doc/src/Makefile
index 5136c7cfb5..4b76a64b7d 100644
--- a/lib/cosEvent/doc/src/Makefile
+++ b/lib/cosEvent/doc/src/Makefile
@@ -65,6 +65,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
TECHNICAL_DESCR_FILES =
GIF_FILES = \
diff --git a/lib/cosEvent/doc/src/notes.xml b/lib/cosEvent/doc/src/notes.xml
index afd1247b42..8cd7b9dd48 100644
--- a/lib/cosEvent/doc/src/notes.xml
+++ b/lib/cosEvent/doc/src/notes.xml
@@ -33,6 +33,20 @@
</header>
<section>
+ <title>cosEvent 2.1.8</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosEvent 2.1.7</title>
<section>
diff --git a/lib/cosEvent/vsn.mk b/lib/cosEvent/vsn.mk
index 953e5fc8c9..7c908d1c5d 100644
--- a/lib/cosEvent/vsn.mk
+++ b/lib/cosEvent/vsn.mk
@@ -1,7 +1,9 @@
-COSEVENT_VSN = 2.1.7
+COSEVENT_VSN = 2.1.8
-TICKETS = OTP-8201
+TICKETS = OTP-8355
+
+TICKETS_2.1.7 = OTP-8201
TICKETS_2.1.6 = OTP-7987
diff --git a/lib/cosEventDomain/doc/src/Makefile b/lib/cosEventDomain/doc/src/Makefile
index 465b726ad1..6a0d3c353a 100644
--- a/lib/cosEventDomain/doc/src/Makefile
+++ b/lib/cosEventDomain/doc/src/Makefile
@@ -62,6 +62,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
TECHNICAL_DESCR_FILES =
GIF_FILES = \
diff --git a/lib/cosEventDomain/doc/src/ch_event_domain_service.xml b/lib/cosEventDomain/doc/src/ch_event_domain_service.xml
index 62378cac91..39ac915b38 100644
--- a/lib/cosEventDomain/doc/src/ch_event_domain_service.xml
+++ b/lib/cosEventDomain/doc/src/ch_event_domain_service.xml
@@ -97,9 +97,9 @@ ID2 = 'CosEventDomainAdmin_EventDomain':add_channel(ED, Ch2),
%% To connect them, we must first define a connection struct:
C1 = #'CosEventDomainAdmin_Connection'{supplier_id=ID1,
-\011\011\011\011 consumer_id=ID2,
-\011\011\011\011 ctype='STRUCTURED_EVENT',
-\011\011\011\011 notification_style='Pull'},
+ consumer_id=ID2,
+ ctype='STRUCTURED_EVENT',
+ notification_style='Pull'},
%% Connect them:
'CosEventDomainAdmin_EventDomain':add_connection(ED, C1),
diff --git a/lib/cosEventDomain/doc/src/notes.xml b/lib/cosEventDomain/doc/src/notes.xml
index fdfb21c046..0ad42948af 100644
--- a/lib/cosEventDomain/doc/src/notes.xml
+++ b/lib/cosEventDomain/doc/src/notes.xml
@@ -32,6 +32,24 @@
</header>
<section>
+ <title>cosEventDomain 1.1.8</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Removed superfluous VT in the documentation.</p>
+ <p>Own id: OTP-8353 Aux Id:</p>
+ </item>
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosEventDomain 1.1.7</title>
<section>
diff --git a/lib/cosEventDomain/vsn.mk b/lib/cosEventDomain/vsn.mk
index 81c0b49143..483b130819 100644
--- a/lib/cosEventDomain/vsn.mk
+++ b/lib/cosEventDomain/vsn.mk
@@ -1,7 +1,10 @@
-COSEVENTDOMAIN_VSN = 1.1.7
+COSEVENTDOMAIN_VSN = 1.1.8
-TICKETS = OTP-8201
+TICKETS = OTP-8353 \
+ OTP-8355
+
+TICKETS_1.1.7 = OTP-8201
TICKETS_1.1.6 = OTP-7987
diff --git a/lib/cosFileTransfer/doc/src/Makefile b/lib/cosFileTransfer/doc/src/Makefile
index 7769d5ef8c..2286db43ff 100644
--- a/lib/cosFileTransfer/doc/src/Makefile
+++ b/lib/cosFileTransfer/doc/src/Makefile
@@ -65,6 +65,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
TECHNICAL_DESCR_FILES =
GIF_FILES = \
diff --git a/lib/cosFileTransfer/doc/src/notes.xml b/lib/cosFileTransfer/doc/src/notes.xml
index e3b7e4819a..5bb2ea68c4 100644
--- a/lib/cosFileTransfer/doc/src/notes.xml
+++ b/lib/cosFileTransfer/doc/src/notes.xml
@@ -31,6 +31,20 @@
</header>
<section>
+ <title>cosFileTransfer 1.1.10</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosFileTransfer 1.1.9</title>
<section>
diff --git a/lib/cosFileTransfer/vsn.mk b/lib/cosFileTransfer/vsn.mk
index dd92b53904..88786178fb 100644
--- a/lib/cosFileTransfer/vsn.mk
+++ b/lib/cosFileTransfer/vsn.mk
@@ -1,9 +1,11 @@
-COSFILETRANSFER_VSN = 1.1.9
+COSFILETRANSFER_VSN = 1.1.10
TICKETS = \
- OTP-8201
+ OTP-8355
+TICKETS_1.1.9 = OTP-8201
+
TICKETS_1.1.8 = OTP-7987
TICKETS_1.1.7 = OTP-7837
diff --git a/lib/cosNotification/doc/src/Makefile b/lib/cosNotification/doc/src/Makefile
index 6abcf0ef1d..bfdd2f1f8c 100644
--- a/lib/cosNotification/doc/src/Makefile
+++ b/lib/cosNotification/doc/src/Makefile
@@ -91,6 +91,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
TECHNICAL_DESCR_FILES =
GIF_FILES = \
diff --git a/lib/cosNotification/doc/src/ch_BNF.xml b/lib/cosNotification/doc/src/ch_BNF.xml
index 545280a1f4..73e91e3cac 100644
--- a/lib/cosNotification/doc/src/ch_BNF.xml
+++ b/lib/cosNotification/doc/src/ch_BNF.xml
@@ -181,7 +181,7 @@ FilterID = 'CosNotifyChannelAdmin_ConsumerAdmin':
/* Character set issues */
<Ident> :=<Leader> <FollowSeq>
- | \\ < Leader> <FollowSeq>
+ | \ < Leader> <FollowSeq>
<FollowSeq> := /* <empty> */
| <FollowSeq> <Follow>
@@ -215,8 +215,8 @@ FilterID = 'CosNotifyChannelAdmin_ConsumerAdmin':
| <Other>
| <Special>
-<Special> := \\\\
- | \\'
+<Special> := \\
+ | \'
<Leader> := <Alpha>
diff --git a/lib/cosNotification/doc/src/ch_example.xml b/lib/cosNotification/doc/src/ch_example.xml
index 8cb12bd241..14c0e5c6fd 100644
--- a/lib/cosNotification/doc/src/ch_example.xml
+++ b/lib/cosNotification/doc/src/ch_example.xml
@@ -124,7 +124,7 @@ ChFac = cosNotificationApp:start_factory([]),
{AdminSupplier, ASID}=
'CosNotifyChannelAdmin_EventChannel':new_for_suppliers(Ch, 'OR_OP'),
{AdminConsumer, ACID}=
-\011'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP'),
+ 'CosNotifyChannelAdmin_EventChannel':new_for_consumers(Ch,'OR_OP'),
%% Use the corresponding Admin object to get access to wanted Proxies
diff --git a/lib/cosNotification/doc/src/notes.xml b/lib/cosNotification/doc/src/notes.xml
index c66be87c7c..29879e95fb 100644
--- a/lib/cosNotification/doc/src/notes.xml
+++ b/lib/cosNotification/doc/src/notes.xml
@@ -32,6 +32,28 @@
</header>
<section>
+ <title>cosNotification 1.1.13</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Removed superfluous VT in the documentation.</p>
+ <p>Own id: OTP-8353 Aux Id:</p>
+ </item>
+ <item>
+ <p>Removed superfluous backslash in the documentation.</p>
+ <p>Own id: OTP-8354 Aux Id:</p>
+ </item>
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosNotification 1.1.12</title>
<section>
diff --git a/lib/cosNotification/vsn.mk b/lib/cosNotification/vsn.mk
index 65f9812f31..fed10ee195 100644
--- a/lib/cosNotification/vsn.mk
+++ b/lib/cosNotification/vsn.mk
@@ -1,6 +1,10 @@
-COSNOTIFICATION_VSN = 1.1.12
+COSNOTIFICATION_VSN = 1.1.13
-TICKETS = OTP-8201
+TICKETS = OTP-8353 \
+ OTP-8354 \
+ OTP-8355
+
+TICKETS_1.1.12 = OTP-8201
TICKETS_1.1.11 = OTP-7987
diff --git a/lib/cosProperty/doc/src/Makefile b/lib/cosProperty/doc/src/Makefile
index 126e05ef53..baf995d35e 100644
--- a/lib/cosProperty/doc/src/Makefile
+++ b/lib/cosProperty/doc/src/Makefile
@@ -67,6 +67,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
TECHNICAL_DESCR_FILES =
GIF_FILES = \
diff --git a/lib/cosProperty/doc/src/notes.xml b/lib/cosProperty/doc/src/notes.xml
index be3a8d0f5e..e80c90849f 100644
--- a/lib/cosProperty/doc/src/notes.xml
+++ b/lib/cosProperty/doc/src/notes.xml
@@ -32,6 +32,20 @@
</header>
<section>
+ <title>cosProperty 1.1.11</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosProperty 1.1.10</title>
<section>
diff --git a/lib/cosProperty/vsn.mk b/lib/cosProperty/vsn.mk
index 0e55352e42..c221e6fa4a 100644
--- a/lib/cosProperty/vsn.mk
+++ b/lib/cosProperty/vsn.mk
@@ -1,6 +1,8 @@
-COSPROPERTY_VSN = 1.1.10
+COSPROPERTY_VSN = 1.1.11
-TICKETS = OTP-8201
+TICKETS = OTP-8355
+
+TICKETS_1.1.10 = OTP-8201
TICKETS_1.1.9 = OTP-7987
diff --git a/lib/cosTime/doc/src/Makefile b/lib/cosTime/doc/src/Makefile
index 568e2cd4cc..83abc5e7c2 100644
--- a/lib/cosTime/doc/src/Makefile
+++ b/lib/cosTime/doc/src/Makefile
@@ -64,6 +64,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
TECHNICAL_DESCR_FILES =
GIF_FILES = \
diff --git a/lib/cosTime/doc/src/notes.xml b/lib/cosTime/doc/src/notes.xml
index afa10980e8..9f23a8633c 100644
--- a/lib/cosTime/doc/src/notes.xml
+++ b/lib/cosTime/doc/src/notes.xml
@@ -33,6 +33,20 @@
</header>
<section>
+ <title>cosTime 1.1.8</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosTime 1.1.7</title>
<section>
diff --git a/lib/cosTime/vsn.mk b/lib/cosTime/vsn.mk
index ac5e99a0f1..db51bf39b9 100644
--- a/lib/cosTime/vsn.mk
+++ b/lib/cosTime/vsn.mk
@@ -1,6 +1,8 @@
-COSTIME_VSN = 1.1.7
+COSTIME_VSN = 1.1.8
-TICKETS = OTP-8201
+TICKETS = OTP-8355
+
+TICKETS_1.1.7 = OTP-8201
TICKETS_1.1.6 = OTP-7987
diff --git a/lib/cosTransactions/doc/src/Makefile b/lib/cosTransactions/doc/src/Makefile
index eab52d3dc9..1af9ed24b7 100644
--- a/lib/cosTransactions/doc/src/Makefile
+++ b/lib/cosTransactions/doc/src/Makefile
@@ -68,6 +68,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
TECHNICAL_DESCR_FILES =
GIF_FILES = \
diff --git a/lib/cosTransactions/doc/src/notes.xml b/lib/cosTransactions/doc/src/notes.xml
index 953382ef87..41a754b034 100644
--- a/lib/cosTransactions/doc/src/notes.xml
+++ b/lib/cosTransactions/doc/src/notes.xml
@@ -33,6 +33,20 @@
</header>
<section>
+ <title>cosTransactions 1.2.9</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>cosTransactions 1.2.8</title>
<section>
diff --git a/lib/cosTransactions/vsn.mk b/lib/cosTransactions/vsn.mk
index 404a9ed7af..81e360ac2f 100644
--- a/lib/cosTransactions/vsn.mk
+++ b/lib/cosTransactions/vsn.mk
@@ -1,6 +1,8 @@
-COSTRANSACTIONS_VSN = 1.2.8
+COSTRANSACTIONS_VSN = 1.2.9
-TICKETS = OTP-8201
+TICKETS = OTP-8355
+
+TICKETS_1.2.8 = OTP-8201
TICKETS_1.2.7 = OTP-7987
diff --git a/lib/crypto/c_src/crypto_drv.c b/lib/crypto/c_src/crypto_drv.c
index 241c4ec733..5b6d750dde 100644
--- a/lib/crypto/c_src/crypto_drv.c
+++ b/lib/crypto/c_src/crypto_drv.c
@@ -233,6 +233,11 @@ static ErlDrvEntry crypto_driver_entry = {
#define DRV_BF_CFB64_ENCRYPT 59
#define DRV_BF_CFB64_DECRYPT 60
+#define DRV_BF_ECB_ENCRYPT 61
+#define DRV_BF_ECB_DECRYPT 62
+#define DRV_BF_OFB64_ENCRYPT 63
+#define DRV_BF_CBC_ENCRYPT 64
+#define DRV_BF_CBC_DECRYPT 65
/* #define DRV_CBC_IDEA_ENCRYPT 34 */
/* #define DRV_CBC_IDEA_DECRYPT 35 */
@@ -533,6 +538,79 @@ static int crypto_control(ErlDrvData drv_data, unsigned int command, char *buf,
(command == DRV_CBC_DES_ENCRYPT));
return dlen;
+ case DRV_BF_ECB_ENCRYPT:
+ case DRV_BF_ECB_DECRYPT:
+ {
+ /* buf = klen[4] key data */
+ int bf_direction;
+ const unsigned char *ukey;
+ const unsigned char *bf_dbuf; /* blowfish input data */
+ BF_KEY bf_key; /* blowfish key 8 */
+
+ klen = get_int32(buf);
+ ukey = (unsigned char *) buf + 4;
+ bf_dbuf = ukey + klen;
+ dlen = len - 4 - klen;
+ if (dlen < 0) return -1;
+ BF_set_key(&bf_key, klen, ukey);
+ bin = return_binary(rbuf,rlen,dlen);
+ if (bin==NULL) return -1;
+ bf_direction = command == DRV_BF_ECB_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT;
+ BF_ecb_encrypt(bf_dbuf, bin, &bf_key, bf_direction);
+ return dlen;
+ }
+
+ case DRV_BF_CBC_ENCRYPT:
+ case DRV_BF_CBC_DECRYPT:
+ {
+ /* buf = klen[4] key ivec[8] data */
+ unsigned char *ukey;
+ unsigned char* ivec;
+ unsigned char bf_tkey[8]; /* blowfish ivec */
+ int bf_direction;
+ const unsigned char *bf_dbuf; /* blowfish input data */
+ BF_KEY bf_key; /* blowfish key 8 */
+
+ klen = get_int32(buf);
+ ukey = (unsigned char *)buf + 4;
+ ivec = ukey + klen;
+ bf_dbuf = ivec + 8;
+ dlen = len - 4 - klen - 8;
+ if (dlen < 0) return -1;
+ BF_set_key(&bf_key, klen, ukey);
+ memcpy(bf_tkey, ivec, 8);
+ bin = return_binary(rbuf,rlen,dlen);
+ if (bin==NULL) return -1;
+ bf_direction = command == DRV_BF_CBC_ENCRYPT ? BF_ENCRYPT : BF_DECRYPT;
+ BF_cbc_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, bf_direction);
+ return dlen;
+ }
+
+ case DRV_BF_OFB64_ENCRYPT:
+ {
+ /* buf = klen[4] key ivec[8] data */
+ unsigned char *ukey;
+ unsigned char* ivec;
+ unsigned char bf_tkey[8]; /* blowfish ivec */
+ int bf_n; /* blowfish ivec pos */
+ const unsigned char *bf_dbuf; /* blowfish input data */
+ BF_KEY bf_key; /* blowfish key 8 */
+
+ klen = get_int32(buf);
+ ukey = (unsigned char *)buf + 4;
+ ivec = ukey + klen;
+ bf_dbuf = ivec + 8;
+ dlen = len - 4 - klen - 8;
+ if (dlen < 0) return -1;
+ BF_set_key(&bf_key, klen, ukey);
+ memcpy(bf_tkey, ivec, 8);
+ bin = return_binary(rbuf,rlen,dlen);
+ if (bin==NULL) return -1;
+ bf_n = 0;
+ BF_ofb64_encrypt(bf_dbuf, bin, dlen, &bf_key, bf_tkey, &bf_n);
+ return dlen;
+ }
+
case DRV_BF_CFB64_ENCRYPT:
case DRV_BF_CFB64_DECRYPT:
{
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 42ba523c8c..cfc6996332 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -337,6 +337,53 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
<c>Key3</c>, and <c>IVec</c> must be 64 bits (8 bytes).</p>
</desc>
</func>
+
+ <func>
+ <name>blowfish_ecb_encrypt(Key, Text) -> Cipher</name>
+ <fsummary>Encrypt the first 64 bits of <c>Text</c> using Blowfish in ECB mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts the first 64 bits of <c>Text</c> using Blowfish in ECB mode. <c>Key</c> is the Blowfish key. The length of <c>Text</c> must be at least 64 bits (8 bytes).</p>
+ </desc>
+ <name>blowfish_ecb_decrypt(Key, Text) -> Cipher</name>
+ <fsummary>Decrypt the first 64 bits of <c>Text</c> using Blowfish in ECB mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Decrypts the first 64 bits of <c>Text</c> using Blowfish in ECB mode. <c>Key</c> is the Blowfish key. The length of <c>Text</c> must be at least 64 bits (8 bytes).</p>
+ </desc>
+ </func>
+
+ <func>
+ <name>blowfish_cbc_encrypt(Key, Text) -> Cipher</name>
+ <fsummary>Encrypt <c>Text</c> using Blowfish in CBC mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts <c>Text</c> using Blowfish in CBC mode. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an
+ arbitrary initializing vector. The length of <c>IVec</c>
+ must be 64 bits (8 bytes). The length of <c>Text</c> must be a multiple of 64 bits (8 bytes).</p>
+ </desc>
+ <name>blowfish_cbc_decrypt(Key, Text) -> Cipher</name>
+ <fsummary>Decrypt <c>Text</c> using Blowfish in CBC mode</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Decrypts <c>Text</c> using Blowfish in CBC mode. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an
+ arbitrary initializing vector. The length of <c>IVec</c>
+ must be 64 bits (8 bytes). The length of <c>Text</c> must be a multiple 64 bits (8 bytes).</p>
+ </desc>
+ </func>
+
<func>
<name>blowfish_cfb64_encrypt(Key, IVec, Text) -> Cipher</name>
<fsummary>Encrypt <c>Text</c>using Blowfish in CFB mode with 64
@@ -367,6 +414,23 @@ Mpint() = <![CDATA[<<ByteLen:32/integer-big, Bytes:ByteLen/binary>>]]>
must be 64 bits (8 bytes).</p>
</desc>
</func>
+
+ <func>
+ <name>blowfish_ofb64_encrypt(Key, IVec, Text) -> Cipher</name>
+ <fsummary>Encrypt <c>Text</c>using Blowfish in OFB mode with 64
+ bit feedback</fsummary>
+ <type>
+ <v>Key = Text = iolist() | binary()</v>
+ <v>IVec = Cipher = binary()</v>
+ </type>
+ <desc>
+ <p>Encrypts <c>Text</c> using Blowfish in OFB mode with 64 bit
+ feedback. <c>Key</c> is the Blowfish key, and <c>IVec</c> is an
+ arbitrary initializing vector. The length of <c>IVec</c>
+ must be 64 bits (8 bytes).</p>
+ </desc>
+ </func>
+
<func>
<name>aes_cfb_128_encrypt(Key, IVec, Text) -> Cipher</name>
<name>aes_cbc_128_encrypt(Key, IVec, Text) -> Cipher</name>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 5189677dd0..fa33bad2e0 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -30,7 +30,10 @@
-export([md5_mac/2, md5_mac_96/2, sha_mac/2, sha_mac_96/2]).
-export([des_cbc_encrypt/3, des_cbc_decrypt/3, des_cbc_ivec/1]).
-export([des3_cbc_encrypt/5, des3_cbc_decrypt/5]).
--export([blowfish_cfb64_encrypt/3,blowfish_cfb64_decrypt/3]).
+-export([blowfish_ecb_encrypt/2, blowfish_ecb_decrypt/2]).
+-export([blowfish_cbc_encrypt/3, blowfish_cbc_decrypt/3]).
+-export([blowfish_cfb64_encrypt/3, blowfish_cfb64_decrypt/3]).
+-export([blowfish_ofb64_encrypt/3]).
-export([des_ede3_cbc_encrypt/5, des_ede3_cbc_decrypt/5]).
-export([aes_cfb_128_encrypt/3, aes_cfb_128_decrypt/3]).
-export([exor/2]).
@@ -115,6 +118,11 @@
-define(BF_CFB64_ENCRYPT, 59).
-define(BF_CFB64_DECRYPT, 60).
+-define(BF_ECB_ENCRYPT, 61).
+-define(BF_ECB_DECRYPT, 62).
+-define(BF_OFB64_ENCRYPT, 63).
+-define(BF_CBC_ENCRYPT, 64).
+-define(BF_CBC_DECRYPT, 65).
%% -define(IDEA_CBC_ENCRYPT, 34).
%% -define(IDEA_CBC_DECRYPT, 35).
@@ -303,12 +311,27 @@ des_ede3_cbc_decrypt(Key1, Key2, Key3, IVec, Data) ->
%%
%% Blowfish
%%
+blowfish_ecb_encrypt(Key, Data) when byte_size(Data) >= 8 ->
+ control_bin(?BF_ECB_ENCRYPT, Key, list_to_binary([Data])).
+
+blowfish_ecb_decrypt(Key, Data) when byte_size(Data) >= 8 ->
+ control_bin(?BF_ECB_DECRYPT, Key, list_to_binary([Data])).
+
+blowfish_cbc_encrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 ->
+ control_bin(?BF_CBC_ENCRYPT, Key, list_to_binary([IVec, Data])).
+
+blowfish_cbc_decrypt(Key, IVec, Data) when byte_size(Data) rem 8 =:= 0 ->
+ control_bin(?BF_CBC_DECRYPT, Key, list_to_binary([IVec, Data])).
+
blowfish_cfb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 ->
control_bin(?BF_CFB64_ENCRYPT, Key, list_to_binary([IVec, Data])).
blowfish_cfb64_decrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 ->
control_bin(?BF_CFB64_DECRYPT, Key, list_to_binary([IVec, Data])).
+blowfish_ofb64_encrypt(Key, IVec, Data) when byte_size(IVec) =:= 8 ->
+ control_bin(?BF_OFB64_ENCRYPT, Key, list_to_binary([IVec, Data])).
+
%%
%% AES in cipher feedback mode (CFB)
%%
diff --git a/lib/crypto/test/Makefile b/lib/crypto/test/Makefile
new file mode 100644
index 0000000000..e728875027
--- /dev/null
+++ b/lib/crypto/test/Makefile
@@ -0,0 +1,83 @@
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES = \
+ blowfish_SUITE \
+ crypto_SUITE
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+TARGET_FILES= $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+SOURCE = $(ERL_FILES) $(HRL_FILES)
+
+EMAKEFILE=Emakefile
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/crypto_test
+
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+ERL_MAKE_FLAGS +=
+ERL_COMPILE_FLAGS += -I$(ERL_TOP)/lib/test_server/include
+
+EBIN = .
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+# Backward compatibility, for R9B and earlier.
+
+ifeq ($(MAKE_EMAKE),)
+
+RELTEST_FILES = $(SOURCE) $(TARGET_FILES)
+TEST_TARGET = tests
+
+tests debug opt: $(TARGET_FILES)
+
+else
+
+RELTEST_FILES = $(EMAKEFILE) $(SOURCE)
+TEST_TARGET = make_emakefile
+
+
+tests debug opt: make_emakefile
+ erl $(ERL_MAKE_FLAGS) -make
+
+make_emakefile:
+ $(ERL_TOP)/make/make_emakefile $(ERL_COMPILE_FLAGS) -o$(EBIN) \
+ $(MODULES) > $(EMAKEFILE)
+
+endif
+clean:
+ rm -f $(EMAKEFILE)
+ rm -f $(TARGET_FILES) $(GEN_FILES)
+ rm -f core
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_tests_spec: $(TEST_TARGET)
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) crypto.spec $(RELTEST_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+
+release_docs_spec:
+
diff --git a/lib/crypto/test/blowfish_SUITE.erl b/lib/crypto/test/blowfish_SUITE.erl
new file mode 100644
index 0000000000..d4cc167ea9
--- /dev/null
+++ b/lib/crypto/test/blowfish_SUITE.erl
@@ -0,0 +1,210 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(blowfish_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+-define(TIMEOUT, 120000). % 2 min
+
+-define(KEY, to_bin("0123456789ABCDEFF0E1D2C3B4A59687")).
+-define(IVEC, to_bin("FEDCBA9876543210")).
+%% "7654321 Now is the time for " (includes trailing '\0')
+-define(DATA, to_bin("37363534333231204E6F77206973207468652074696D6520666F722000")).
+-define(DATA_PADDED, to_bin("37363534333231204E6F77206973207468652074696D6520666F722000000000")).
+
+%% Test server callback functions
+%%--------------------------------------------------------------------
+%% Function: init_per_suite(Config) -> Config
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Initialization before the whole suite
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%%--------------------------------------------------------------------
+init_per_suite(Config) ->
+ crypto:start(),
+ Config.
+
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ crypto:stop().
+
+%%--------------------------------------------------------------------
+%% Function: init_per_testcase(TestCase, Config) -> Config
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%%
+%% Description: Initialization before each test case
+%%
+%% Note: This function is free to add any key/value pairs to the Config
+%% variable, but should NOT alter/remove any existing entries.
+%% Description: Initialization before each test case
+%%--------------------------------------------------------------------
+init_per_testcase(_TestCase, Config0) ->
+ Config = lists:keydelete(watchdog, 1, Config0),
+ Dog = test_server:timetrap(?TIMEOUT),
+ [{watchdog, Dog} | Config].
+
+%%--------------------------------------------------------------------
+%% Function: end_per_testcase(TestCase, Config) -> _
+%% Case - atom()
+%% Name of the test case that is about to be run.
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after each test case
+%%--------------------------------------------------------------------
+end_per_testcase(_TestCase, Config) ->
+ Dog = ?config(watchdog, Config),
+ case Dog of
+ undefined ->
+ ok;
+ _ ->
+ test_server:timetrap_cancel(Dog)
+ end.
+
+%%--------------------------------------------------------------------
+%% Function: all(Clause) -> TestCases
+%% Clause - atom() - suite | doc
+%% TestCases - [Case]
+%% Case - atom()
+%% Name of a test case.
+%% Description: Returns a list of all test cases in this test suite
+%%--------------------------------------------------------------------
+all(doc) ->
+ ["Test Blowfish functionality"];
+
+all(suite) ->
+ [ecb,
+ cbc,
+ cfb64,
+ ofb64
+ ].
+
+%% Test cases start here.
+%%--------------------------------------------------------------------
+
+ecb_test(KeyBytes, ClearBytes, CipherBytes) ->
+ {Key, Clear, Cipher} =
+ {to_bin(KeyBytes), to_bin(ClearBytes), to_bin(CipherBytes)},
+ crypto:blowfish_ecb_encrypt(Key, Clear) =:= Cipher.
+
+ecb(doc) ->
+ "Test that ECB mode is OK";
+ecb(suite) ->
+ [];
+ecb(Config) when is_list(Config) ->
+ true = ecb_test("0000000000000000", "0000000000000000", "4EF997456198DD78"),
+ true = ecb_test("FFFFFFFFFFFFFFFF", "FFFFFFFFFFFFFFFF", "51866FD5B85ECB8A"),
+ true = ecb_test("3000000000000000", "1000000000000001", "7D856F9A613063F2"),
+ true = ecb_test("1111111111111111", "1111111111111111", "2466DD878B963C9D"),
+ true = ecb_test("0123456789ABCDEF", "1111111111111111", "61F9C3802281B096"),
+ true = ecb_test("1111111111111111", "0123456789ABCDEF", "7D0CC630AFDA1EC7"),
+ true = ecb_test("0000000000000000", "0000000000000000", "4EF997456198DD78"),
+ true = ecb_test("FEDCBA9876543210", "0123456789ABCDEF", "0ACEAB0FC6A0A28D"),
+ true = ecb_test("7CA110454A1A6E57", "01A1D6D039776742", "59C68245EB05282B"),
+ true = ecb_test("0131D9619DC1376E", "5CD54CA83DEF57DA", "B1B8CC0B250F09A0"),
+ true = ecb_test("07A1133E4A0B2686", "0248D43806F67172", "1730E5778BEA1DA4"),
+ true = ecb_test("3849674C2602319E", "51454B582DDF440A", "A25E7856CF2651EB"),
+ true = ecb_test("04B915BA43FEB5B6", "42FD443059577FA2", "353882B109CE8F1A"),
+ true = ecb_test("0113B970FD34F2CE", "059B5E0851CF143A", "48F4D0884C379918"),
+ true = ecb_test("0170F175468FB5E6", "0756D8E0774761D2", "432193B78951FC98"),
+ true = ecb_test("43297FAD38E373FE", "762514B829BF486A", "13F04154D69D1AE5"),
+ true = ecb_test("07A7137045DA2A16", "3BDD119049372802", "2EEDDA93FFD39C79"),
+ true = ecb_test("04689104C2FD3B2F", "26955F6835AF609A", "D887E0393C2DA6E3"),
+ true = ecb_test("37D06BB516CB7546", "164D5E404F275232", "5F99D04F5B163969"),
+ true = ecb_test("1F08260D1AC2465E", "6B056E18759F5CCA", "4A057A3B24D3977B"),
+ true = ecb_test("584023641ABA6176", "004BD6EF09176062", "452031C1E4FADA8E"),
+ true = ecb_test("025816164629B007", "480D39006EE762F2", "7555AE39F59B87BD"),
+ true = ecb_test("49793EBC79B3258F", "437540C8698F3CFA", "53C55F9CB49FC019"),
+ true = ecb_test("4FB05E1515AB73A7", "072D43A077075292", "7A8E7BFA937E89A3"),
+ true = ecb_test("49E95D6D4CA229BF", "02FE55778117F12A", "CF9C5D7A4986ADB5"),
+ true = ecb_test("018310DC409B26D6", "1D9D5C5018F728C2", "D1ABB290658BC778"),
+ true = ecb_test("1C587F1C13924FEF", "305532286D6F295A", "55CB3774D13EF201"),
+ true = ecb_test("0101010101010101", "0123456789ABCDEF", "FA34EC4847B268B2"),
+ true = ecb_test("1F1F1F1F0E0E0E0E", "0123456789ABCDEF", "A790795108EA3CAE"),
+ true = ecb_test("E0FEE0FEF1FEF1FE", "0123456789ABCDEF", "C39E072D9FAC631D"),
+ true = ecb_test("0000000000000000", "FFFFFFFFFFFFFFFF", "014933E0CDAFF6E4"),
+ true = ecb_test("FFFFFFFFFFFFFFFF", "0000000000000000", "F21E9A77B71C49BC"),
+ true = ecb_test("0123456789ABCDEF", "0000000000000000", "245946885754369A"),
+ true = ecb_test("FEDCBA9876543210", "FFFFFFFFFFFFFFFF", "6B5C5A9C5D9E0A5A"),
+ ok.
+
+cbc(doc) ->
+ "Test that CBC mode is OK";
+cbc(suite) ->
+ [];
+cbc(Config) when is_list(Config) ->
+ true = crypto:blowfish_cbc_encrypt(?KEY, ?IVEC, ?DATA_PADDED) =:=
+ to_bin("6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC"),
+ ok.
+
+cfb64(doc) ->
+ "Test that CFB64 mode is OK";
+cfb64(suite) ->
+ [];
+cfb64(Config) when is_list(Config) ->
+ true = crypto:blowfish_cfb64_encrypt(?KEY, ?IVEC, ?DATA) =:=
+ to_bin("E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3"),
+ ok.
+
+ofb64(doc) ->
+ "Test that OFB64 mode is OK";
+ofb64(suite) ->
+ [];
+ofb64(Config) when is_list(Config) ->
+ true = crypto:blowfish_ofb64_encrypt(?KEY, ?IVEC, ?DATA) =:=
+ to_bin("E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA"),
+ ok.
+
+%% Helper functions
+
+%% Convert a hexadecimal string to a binary.
+-spec(to_bin(L::string()) -> binary()).
+to_bin(L) ->
+ to_bin(L, []).
+
+%% @spec dehex(char()) -> integer()
+%% @doc Convert a hex digit to its integer value.
+-spec(dehex(char()) -> integer()).
+dehex(C) when C >= $0, C =< $9 ->
+ C - $0;
+dehex(C) when C >= $a, C =< $f ->
+ C - $a + 10;
+dehex(C) when C >= $A, C =< $F ->
+ C - $A + 10.
+
+-spec(to_bin(L::string(), list()) -> binary()).
+to_bin([], Acc) ->
+ iolist_to_binary(lists:reverse(Acc));
+to_bin([C1, C2 | Rest], Acc) ->
+ to_bin(Rest, [(dehex(C1) bsl 4) bor dehex(C2) | Acc]).
diff --git a/lib/crypto/test/crypto.spec b/lib/crypto/test/crypto.spec
new file mode 100644
index 0000000000..7ba5696189
--- /dev/null
+++ b/lib/crypto/test/crypto.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../crypto_test"}}.
+
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
new file mode 100644
index 0000000000..290ef19160
--- /dev/null
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -0,0 +1,1110 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+-module(crypto_SUITE).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+
+-export([all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+ info/1,
+ link_test/1,
+ md5/1,
+ md5_update/1,
+ md4/1,
+ md4_update/1,
+ sha/1,
+ sha_update/1,
+ sha256/1,
+ sha256_update/1,
+ sha512/1,
+ sha512_update/1,
+ md5_mac/1,
+ md5_mac_io/1,
+ des_cbc/1,
+ des_cbc_iter/1,
+ aes_cfb/1,
+ aes_cbc/1,
+ aes_cbc_iter/1,
+ mod_exp_test/1,
+ rand_uniform_test/1,
+ rsa_verify_test/1,
+ dsa_verify_test/1,
+ rsa_sign_test/1,
+ dsa_sign_test/1,
+ rsa_encrypt_decrypt/1,
+ dh/1,
+ exor_test/1,
+ rc4_test/1,
+ blowfish_cfb64/1,
+ smp/1,
+ cleanup/1]).
+
+-export([hexstr2bin/1]).
+
+all(suite) ->
+ [link_test,
+ {conf,info,[md5,
+ md5_update,
+ md4,
+ md4_update,
+ md5_mac,
+ md5_mac_io,
+ sha,
+ sha_update,
+%% sha256,
+%% sha256_update,
+%% sha512,
+%% sha512_update,
+ des_cbc,
+ aes_cfb,
+ aes_cbc,
+ aes_cbc_iter,
+ des_cbc_iter,
+ rand_uniform_test,
+ rsa_verify_test,
+ dsa_verify_test,
+ rsa_sign_test,
+ dsa_sign_test,
+ rsa_encrypt_decrypt,
+ dh,
+ exor_test,
+ rc4_test,
+ mod_exp_test,
+ blowfish_cfb64,
+ smp],
+ cleanup}].
+
+init_per_testcase(_Name,Config) ->
+ io:format("init_per_testcase\n"),
+ ?line crypto:start(),
+ Config.
+
+fin_per_testcase(_Name,Config) ->
+ io:format("fin_per_testcase\n"),
+ ?line crypto:stop(),
+ Config.
+
+%%
+%%
+link_test(doc) ->
+ ["Test that the library is statically linked to libcrypto.a."];
+link_test(suite) ->
+ [];
+link_test(Config) when is_list(Config) ->
+ ?line case os:type() of
+ {unix,darwin} -> {skipped,"Darwin cannot link statically"};
+ {unix,_} -> link_test_1();
+ _ -> {skip,"Only runs on Unix"}
+ end.
+
+link_test_1() ->
+ ?line CryptoPriv = code:priv_dir(crypto),
+ ?line Wc = filename:join([CryptoPriv,"lib","crypto_drv.*"]),
+ ?line case filelib:wildcard(Wc) of
+ [] -> {skip,"Didn't find the crypto driver"};
+ [Drv] -> link_test_2(Drv)
+ end.
+
+link_test_2(Drv) ->
+ case ldd_program() of
+ none ->
+ {skip,"No ldd-like program found"};
+ Ldd ->
+ Cmd = Ldd ++ " " ++ Drv,
+ Libs = os:cmd(Cmd),
+ io:format("~p\n", [Libs]),
+ case string:str(Libs, "libcrypto") of
+ 0 -> ok;
+ _ ->
+ case ?t:is_commercial() of
+ true ->
+ ?t:fail({libcrypto,not_statically_linked});
+ false ->
+ {comment,"Not statically linked (OK for open-source platform)"}
+ end
+ end
+ end.
+
+ldd_program() ->
+ case os:find_executable("ldd") of
+ false ->
+ case os:type() of
+ {unix,darwin} ->
+ case os:find_executable("otool") of
+ false -> none;
+ Otool -> Otool ++ " -L"
+ end
+ end;
+ Ldd when is_list(Ldd) -> Ldd
+ end.
+
+%%
+%%
+info(doc) ->
+ ["Call the info function."];
+info(suite) ->
+ [];
+info(Config) when is_list(Config) ->
+ case {code:lib_dir(crypto),?t:is_commercial()} of
+ {{error,bad_name},false} ->
+ {skip,"Missing crypto application"};
+ {_,_} ->
+ ?line crypto:start(),
+ ?line crypto:info(),
+ ?line InfoLib = crypto:info_lib(),
+ ?line [_|_] = InfoLib,
+ F = fun([{Name,VerN,VerS}|T],Me) ->
+ ?line true = is_binary(Name),
+ ?line true = is_integer(VerN),
+ ?line true = is_binary(VerS),
+ Me(T,Me);
+ ([],_) ->
+ ok
+ end,
+ ?line F(InfoLib,F),
+ ?line crypto:stop()
+ end.
+
+cleanup(doc) ->
+ ["Cleanup (dummy)."];
+cleanup(suite) ->
+ [];
+cleanup(Config) when is_list(Config) ->
+ Config.
+
+%%
+%%
+md5(doc) ->
+ ["Generate MD5 message digests and check the result. Examples are "
+ "from RFC-1321."];
+md5(suite) ->
+ [];
+md5(Config) when is_list(Config) ->
+ ?line m(crypto:md5(""),
+ hexstr2bin("d41d8cd98f00b204e9800998ecf8427e")),
+ ?line m(crypto:md5("a"),
+ hexstr2bin("0cc175b9c0f1b6a831c399e269772661")),
+ ?line m(crypto:md5("abc"),
+ hexstr2bin("900150983cd24fb0d6963f7d28e17f72")),
+ ?line m(crypto:md5("message digest"),
+ hexstr2bin("f96b697d7cb7938d525a2f31aaf161d0")),
+ ?line m(crypto:md5("abcdefghijklmnopqrstuvwxyz"),
+ hexstr2bin("c3fcd3d76192e4007dfb496cca67e13b")),
+ ?line m(crypto:md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ "0123456789"),
+ hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")),
+ ?line m(crypto:md5("12345678901234567890123456789012345678901234567890"
+ "123456789012345678901234567890"),
+ hexstr2bin("57edf4a22be3c955ac49da2e2107b67a")).
+
+%%
+%%
+md5_update(doc) ->
+ ["Generate MD5 message using md5_init, md5_update, and md5_final, and"
+ "check the result. Examples are from RFC-1321."];
+md5_update(suite) ->
+ [];
+md5_update(Config) when is_list(Config) ->
+ ?line Ctx = crypto:md5_init(),
+ ?line Ctx1 = crypto:md5_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ ?line Ctx2 = crypto:md5_update(Ctx1, "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"),
+ ?line m(crypto:md5_final(Ctx2),
+ hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f")).
+
+%%
+%%
+md4(doc) ->
+ ["Generate MD4 message digests and check the result. Examples are "
+ "from RFC-1321."];
+md4(suite) ->
+ [];
+md4(Config) when is_list(Config) ->
+ ?line m(crypto:md4(""),
+ hexstr2bin("31d6cfe0d16ae931b73c59d7e0c089c0")),
+ ?line m(crypto:md4("a"),
+ hexstr2bin("bde52cb31de33e46245e05fbdbd6fb24")),
+ ?line m(crypto:md4("abc"),
+ hexstr2bin("a448017aaf21d8525fc10ae87aa6729d")),
+ ?line m(crypto:md4("message digest"),
+ hexstr2bin("d9130a8164549fe818874806e1c7014b")),
+ ?line m(crypto:md4("abcdefghijklmnopqrstuvwxyz"),
+ hexstr2bin("d79e1c308aa5bbcdeea8ed63df412da9")),
+ ?line m(crypto:md4("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ "0123456789"),
+ hexstr2bin("043f8582f241db351ce627e153e7f0e4")),
+ ?line m(crypto:md4("12345678901234567890123456789012345678901234567890"
+ "123456789012345678901234567890"),
+ hexstr2bin("e33b4ddc9c38f2199c3e7b164fcc0536")).
+
+%%
+%%
+md4_update(doc) ->
+ ["Generate MD5 message using md5_init, md5_update, and md5_final, and"
+ "check the result. Examples are from RFC-1321."];
+md4_update(suite) ->
+ [];
+md4_update(Config) when is_list(Config) ->
+ ?line Ctx = crypto:md4_init(),
+ ?line Ctx1 = crypto:md4_update(Ctx, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
+ ?line Ctx2 = crypto:md4_update(Ctx1, "abcdefghijklmnopqrstuvwxyz"
+ "0123456789"),
+ ?line m(crypto:md4_final(Ctx2),
+ hexstr2bin("043f8582f241db351ce627e153e7f0e4")).
+
+%%
+%%
+sha(doc) ->
+ ["Generate SHA message digests and check the result. Examples are "
+ "from FIPS-180-1."];
+sha(suite) ->
+ [];
+sha(Config) when is_list(Config) ->
+ ?line m(crypto:sha("abc"),
+ hexstr2bin("A9993E364706816ABA3E25717850C26C9CD0D89D")),
+ ?line m(crypto:sha("abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
+ "nlmnomnopnopq"),
+ hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")).
+
+
+%%
+%%
+sha_update(doc) ->
+ ["Generate SHA message digests by using sha_init, sha_update, and"
+ "sha_final, and check the result. Examples are from FIPS-180-1."];
+sha_update(suite) ->
+ [];
+sha_update(Config) when is_list(Config) ->
+ ?line Ctx = crypto:sha_init(),
+ ?line Ctx1 = crypto:sha_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
+ ?line Ctx2 = crypto:sha_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
+ ?line m(crypto:sha_final(Ctx2),
+ hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")).
+
+%%
+%%
+sha256(doc) ->
+ ["Generate SHA-256 message digests and check the result. Examples are "
+ "from rfc-4634."];
+sha256(suite) ->
+ [];
+sha256(Config) when is_list(Config) ->
+ ?line m(crypto:sha256("abc"),
+ hexstr2bin("BA7816BF8F01CFEA4141"
+ "40DE5DAE2223B00361A396177A9CB410FF61F20015AD")),
+ ?line m(crypto:sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklm"
+ "nlmnomnopnopq"),
+ hexstr2bin("248D6A61D20638B8"
+ "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")).
+
+%%
+%%
+sha256_update(doc) ->
+ ["Generate SHA256 message digests by using sha256_init, sha256_update, and"
+ "sha256_final, and check the result. Examples are from rfc-4634."];
+sha256_update(suite) ->
+ [];
+sha256_update(Config) when is_list(Config) ->
+ ?line Ctx = crypto:sha256_init(),
+ ?line Ctx1 = crypto:sha256_update(Ctx, "abcdbcdecdefdefgefghfghighi"),
+ ?line Ctx2 = crypto:sha256_update(Ctx1, "jhijkijkljklmklmnlmnomnopnopq"),
+ ?line m(crypto:sha256_final(Ctx2),
+ hexstr2bin("248D6A61D20638B8"
+ "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")).
+
+
+%%
+%%
+sha512(doc) ->
+ ["Generate SHA-512 message digests and check the result. Examples are "
+ "from rfc-4634."];
+sha512(suite) ->
+ [];
+sha512(Config) when is_list(Config) ->
+ ?line m(crypto:sha512("abc"),
+ hexstr2bin("DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2"
+ "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD"
+ "454D4423643CE80E2A9AC94FA54CA49F")),
+ ?line m(crypto:sha512("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
+ hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1"
+ "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A"
+ "C7D329EEB6DD26545E96E55B874BE909")).
+
+%%
+%%
+sha512_update(doc) ->
+ ["Generate SHA512 message digests by using sha512_init, sha512_update, and"
+ "sha512_final, and check the result. Examples are from rfc=4634."];
+sha512_update(suite) ->
+ [];
+sha512_update(Config) when is_list(Config) ->
+ ?line Ctx = crypto:sha512_init(),
+ ?line Ctx1 = crypto:sha512_update(Ctx, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"),
+ ?line Ctx2 = crypto:sha512_update(Ctx1, "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"),
+ ?line m(crypto:sha512_final(Ctx2),
+ hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1"
+ "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A"
+ "C7D329EEB6DD26545E96E55B874BE909")).
+
+%%
+%%
+md5_mac(doc) ->
+ ["Generate some HMACs, using MD5, and check the result. Examples are "
+ "from RFC-2104."];
+md5_mac(suite) ->
+ [];
+md5_mac(Config) when is_list(Config) ->
+ ?line m(crypto:md5_mac(hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
+ "Hi There"),
+ hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")),
+ ?line m(crypto:md5_mac(list_to_binary("Jefe"),
+ "what do ya want for nothing?"),
+ hexstr2bin("750c783e6ab0b503eaa86e310a5db738")),
+ ?line m(crypto:md5_mac(hexstr2bin("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
+ hexstr2bin("DDDDDDDDDDDDDDDDDDDD"
+ "DDDDDDDDDDDDDDDDDDDD"
+ "DDDDDDDDDDDDDDDDDDDD"
+ "DDDDDDDDDDDDDDDDDDDD"
+ "DDDDDDDDDDDDDDDDDDDD")),
+ hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6")).
+
+%%
+%%
+md5_mac_io(doc) ->
+ ["Generate some HMACs, using MD5, with Key an IO-list, and check the "
+ "result. Examples are from RFC-2104."];
+md5_mac_io(suite) ->
+ [];
+md5_mac_io(Config) when is_list(Config) ->
+ ?line Key1 = hexstr2bin("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"),
+ ?line {B11, B12} = split_binary(Key1, 4),
+ ?line Key11 = [B11,binary_to_list(B12)],
+ ?line m(crypto:md5_mac(Key11, "Hi There"),
+ hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d")).
+
+%%
+%%
+des_cbc(doc) ->
+ "Encrypt and decrypt according to CBC DES. and check the result. "
+ "Example are from FIPS-81.";
+des_cbc(suite) ->
+ [];
+des_cbc(Config) when is_list(Config) ->
+ ?line Key = hexstr2bin("0123456789abcdef"),
+ ?line IVec = hexstr2bin("1234567890abcdef"),
+ ?line Plain = "Now is the time for all ",
+ ?line Cipher = crypto:des_cbc_encrypt(Key, IVec, Plain),
+ ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
+ "0f683788499a7c05f6")),
+ ?line m(list_to_binary(Plain),
+ crypto:des_cbc_decrypt(Key, IVec, Cipher)),
+ ?line Plain2 = "7654321 Now is the time for " ++ [0, 0, 0, 0],
+ ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec, Plain2),
+ ?line m(Cipher2, hexstr2bin("b9916b8ee4c3da64b4f44e3cbefb9"
+ "9484521388fa59ae67d58d2e77e86062733")),
+ ?line m(list_to_binary(Plain2),
+ crypto:des_cbc_decrypt(Key, IVec, Cipher2)).
+
+%%
+%%
+des_cbc_iter(doc) ->
+ "Encrypt and decrypt according to CBC DES in two steps, and "
+ "check the result. Example are from FIPS-81.";
+des_cbc_iter(suite) ->
+ [];
+des_cbc_iter(Config) when is_list(Config) ->
+ ?line Key = hexstr2bin("0123456789abcdef"),
+ ?line IVec = hexstr2bin("1234567890abcdef"),
+ ?line Plain1 = "Now is the time ",
+ ?line Plain2 = "for all ",
+ ?line Cipher1 = crypto:des_cbc_encrypt(Key, IVec, Plain1),
+ ?line IVec2 = crypto:des_cbc_ivec(Cipher1),
+ ?line Cipher2 = crypto:des_cbc_encrypt(Key, IVec2, Plain2),
+ ?line Cipher = concat_binary([Cipher1, Cipher2]),
+ ?line m(Cipher, hexstr2bin("e5c7cdde872bf27c43e934008c389c"
+ "0f683788499a7c05f6")).
+
+%%
+%%
+aes_cfb(doc) ->
+ "Encrypt and decrypt according to AES CFB 128 bit and check "
+ "the result. Example are from NIST SP 800-38A.";
+
+aes_cfb(suite) ->
+ [];
+aes_cfb(Config) when is_list(Config) ->
+
+%% Sample data from NIST Spec.Publ. 800-38A
+%% F.3.13 CFB128-AES128.Encrypt
+%% Key 2b7e151628aed2a6abf7158809cf4f3c
+%% IV 000102030405060708090a0b0c0d0e0f
+%% Segment #1
+%% Input Block 000102030405060708090a0b0c0d0e0f
+%% Output Block 50fe67cc996d32b6da0937e99bafec60
+%% Plaintext 6bc1bee22e409f96e93d7e117393172a
+%% Ciphertext 3b3fd92eb72dad20333449f8e83cfb4a
+%% Segment #2
+%% Input Block 3b3fd92eb72dad20333449f8e83cfb4a
+%% Output Block 668bcf60beb005a35354a201dab36bda
+%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
+%% Ciphertext c8a64537a0b3a93fcde3cdad9f1ce58b
+%% Segment #3
+%% Input Block c8a64537a0b3a93fcde3cdad9f1ce58b
+%% Output Block 16bd032100975551547b4de89daea630
+%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
+%% Ciphertext 26751f67a3cbb140b1808cf187a4f4df
+%% Segment #4
+%% Input Block 26751f67a3cbb140b1808cf187a4f4df
+%% Output Block 36d42170a312871947ef8714799bc5f6
+%% Plaintext f69f2445df4f9b17ad2b417be66c3710
+%% Ciphertext c04b05357c5d1c0eeac4c66f9ff7f2e6
+
+ ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
+ ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"),
+ ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"),
+ ?line Cipher = crypto:aes_cfb_128_encrypt(Key, IVec, Plain),
+ ?line m(Cipher, hexstr2bin("3b3fd92eb72dad20333449f8e83cfb4a")),
+ ?line m(Plain,
+ crypto:aes_cfb_128_decrypt(Key, IVec, Cipher)).
+
+%%
+%%
+aes_cbc(doc) ->
+ "Encrypt and decrypt according to AES CBC 128 bit. and check the result. "
+ "Example are from NIST SP 800-38A.";
+
+aes_cbc(suite) ->
+ [];
+aes_cbc(Config) when is_list(Config) ->
+
+%% Sample data from NIST Spec.Publ. 800-38A
+%% F.2.1 CBC-AES128.Encrypt
+%% Key 2b7e151628aed2a6abf7158809cf4f3c
+%% IV 000102030405060708090a0b0c0d0e0f
+%% Block #1
+%% Plaintext 6bc1bee22e409f96e93d7e117393172a
+%% Input Block 6bc0bce12a459991e134741a7f9e1925
+%% Output Block 7649abac8119b246cee98e9b12e9197d
+%% Ciphertext 7649abac8119b246cee98e9b12e9197d
+%% Block #2
+%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
+%% Input Block d86421fb9f1a1eda505ee1375746972c
+%% Output Block 5086cb9b507219ee95db113a917678b2
+%% Ciphertext 5086cb9b507219ee95db113a917678b2
+%% Block #3
+%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
+%% Input Block 604ed7ddf32efdff7020d0238b7c2a5d
+%% Output Block 73bed6b8e3c1743b7116e69e22229516
+%% Ciphertext 73bed6b8e3c1743b7116e69e22229516
+%% Block #4
+%% Plaintext f69f2445df4f9b17ad2b417be66c3710
+%% Input Block 8521f2fd3c8eef2cdc3da7e5c44ea206
+%% Output Block 3ff1caa1681fac09120eca307586e1a7
+%% Ciphertext 3ff1caa1681fac09120eca307586e1a7
+%%
+%% F.2.2 CBC-AES128.Decrypt
+%% Key 2b7e151628aed2a6abf7158809cf4f3c
+%% IV 000102030405060708090a0b0c0d0e0f
+ %% Block #1
+%% Ciphertext 7649abac8119b246cee98e9b12e9197d
+%% Input Block 7649abac8119b246cee98e9b12e9197d
+%% Output Block 6bc0bce12a459991e134741a7f9e1925
+%% Plaintext 6bc1bee22e409f96e93d7e117393172a
+%% Block #2
+%% Ciphertext 5086cb9b507219ee95db113a917678b2
+%% Input Block 5086cb9b507219ee95db113a917678b2
+%% Output Block d86421fb9f1a1eda505ee1375746972c
+%% Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
+%% Block #3
+%% Ciphertext 73bed6b8e3c1743b7116e69e22229516
+%% Input Block 73bed6b8e3c1743b7116e69e22229516
+%% Output Block 604ed7ddf32efdff7020d0238b7c2a5d
+%% Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
+%% Block #4
+%% Ciphertext 3ff1caa1681fac09120eca307586e1a7
+%% Input Block 3ff1caa1681fac09120eca307586e1a7
+%% Output Block 8521f2fd3c8eef2cdc3da7e5c44ea206
+%% Plaintext f69f2445df4f9b17ad2b417be66c3710
+
+ ?line Key = hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
+ ?line IVec = hexstr2bin("000102030405060708090a0b0c0d0e0f"),
+ ?line Plain = hexstr2bin("6bc1bee22e409f96e93d7e117393172a"),
+ ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain),
+ ?line m(Cipher, hexstr2bin("7649abac8119b246cee98e9b12e9197d")),
+ ?line m(Plain,
+ crypto:aes_cbc_128_decrypt(Key, IVec, Cipher)).
+
+aes_cbc_iter(doc) ->
+ "Encrypt and decrypt according to CBC AES in steps";
+aes_cbc_iter(suite) -> [];
+aes_cbc_iter(Config) when is_list(Config) ->
+ Key = list_to_binary(lists:seq(255,256-16*17,-17)),
+ IVec = list_to_binary(lists:seq(1,16*7,7)),
+ Plain = <<"One, two, three o'clock, four o'clock, rock"
+ "Five, six, seven o'clock, eight o'clock, rock"
+ "Nine, ten, eleven o'clock, twelve o'clock, rock"
+ "We're gonna rock around the clock tonight">>,
+ ?line 0 = size(Plain) rem 16,
+
+ ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Plain),
+ ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Cipher),
+
+ ?line Cipher = aes_cbc_encrypt_iter(Key,IVec,Plain,<<>>),
+ ?line Plain = aes_cbc_decrypt_iter(Key,IVec,Cipher,<<>>),
+ ok.
+
+aes_cbc_encrypt_iter(_,_,<<>>, Acc) ->
+ Acc;
+aes_cbc_encrypt_iter(Key,IVec,Data, Acc) ->
+ Bytes = 16 * (1 + size(Data) div (16*3)),
+ <<Chunk:Bytes/binary, Rest/binary>> = Data,
+ %%io:format("encrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]),
+ ?line Cipher = crypto:aes_cbc_128_encrypt(Key, IVec, Chunk),
+ ?line IVec2 = crypto:aes_cbc_ivec(Cipher),
+ aes_cbc_encrypt_iter(Key,IVec2,Rest, <<Acc/binary, Cipher/binary>>).
+
+aes_cbc_decrypt_iter(_,_,<<>>, Acc) ->
+ Acc;
+aes_cbc_decrypt_iter(Key,IVec,Data, Acc) ->
+ Bytes = 16 * (1 + size(Data) div (16*5)),
+ <<Chunk:Bytes/binary, Rest/binary>> = Data,
+ %%io:format("decrypt iter Chunk=~p Rest=~p\n",[Chunk,Rest]),
+ ?line Plain = crypto:aes_cbc_128_decrypt(Key, IVec, Chunk),
+ ?line IVec2 = crypto:aes_cbc_ivec(Chunk),
+ aes_cbc_decrypt_iter(Key,IVec2,Rest, <<Acc/binary, Plain/binary>>).
+
+
+%%
+%%
+mod_exp_test(doc) ->
+ "mod_exp testing (A ^ M % P with bignums)";
+mod_exp_test(suite) ->
+ [];
+mod_exp_test(Config) when is_list(Config) ->
+ mod_exp_aux_test(2, 5, 10, 8).
+
+mod_exp_aux_test(_, _, _, 0) ->
+ ok;
+mod_exp_aux_test(B, E, M, N) ->
+ ?line R1 = crypto:mod_exp(B, E, M),
+ ?line R2 = ipow(B, E, M),
+ ?line m(R1, R2),
+ ?line mod_exp_aux_test(B, E*E+1, M*M+1, N-1).
+
+%%
+%%
+rand_uniform_test(doc) ->
+ "rand_uniform and random_bytes testing";
+rand_uniform_test(suite) ->
+ [];
+rand_uniform_test(Config) when is_list(Config) ->
+ rand_uniform_aux_test(10),
+ ?line 10 = size(crypto:rand_bytes(10)).
+
+rand_uniform_aux_test(0) ->
+ ok;
+rand_uniform_aux_test(N) ->
+ ?line L = N*1000,
+ ?line H = N*100000+1,
+ ?line R1 = crypto:rand_uniform(L, H),
+ ?line t(R1 >= L),
+ ?line t(R1 < H),
+ ?line rand_uniform_aux_test(N-1).
+
+%%
+%%
+%%
+%%
+rsa_verify_test(doc) ->
+ "rsa_verify testing (A ^ M % P with bignums)";
+rsa_verify_test(suite) ->
+ [];
+rsa_verify_test(Config) when is_list(Config) ->
+ ?line H = <<178,28,54,104,36,80,144,66,140,201,135,17,36,97,114,124,
+ 194,164,172,147>>,
+ ?line SigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70,
+ 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241,
+ 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23,
+ 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76,
+ 115,34,107,227,151,47,80,185,143,85,202,55,245,163,226,26,
+ 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180,
+ 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14,
+ 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>,
+ ?line BadSigBlob = <<153,44,121,71,132,1,192,159,78,33,29,62,153,64,191,70,
+ 208,239,166,208,220,167,49,111,128,67,91,253,24,63,194,241,
+ 97,157,135,226,121,162,150,156,60,49,236,90,151,67,239,23,
+ 92,103,89,254,17,165,78,181,64,128,13,210,86,111,209,76,
+ 115,107,34,227,151,47,80,185,143,85,202,55,245,163,226,26,
+ 139,104,196,6,96,82,108,197,13,0,12,70,153,109,107,180,
+ 130,246,156,182,56,96,31,220,227,218,136,211,252,43,8,14,
+ 145,155,191,206,72,194,80,52,54,206,53,27,6,188,195,29>>,
+ ?line E = <<35>>,
+ ?line N = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10,
+ 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193,
+ 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6,
+ 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1,
+ 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123,
+ 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50,
+ 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73,
+ 76,89,40,33,147,208,189,76,98,24,61,8,10,110,165,119,165>>,
+ ?line Nbad = <<0,199,209,142,191,86,92,148,103,37,250,217,175,169,109,10,
+ 130,139,34,237,174,90,97,118,7,185,57,137,252,236,177,193,
+ 228,16,62,29,153,144,64,207,152,240,152,206,136,89,64,6,
+ 3,187,89,57,241,219,88,215,75,70,120,20,145,229,37,1,
+ 67,138,204,17,39,231,249,239,116,142,169,99,149,41,65,123,
+ 26,225,133,0,41,85,77,181,35,100,162,223,92,220,207,50,
+ 63,168,193,171,174,199,23,214,201,63,157,76,125,6,54,73,
+ 76,89,40,33,147,189,208,76,98,24,61,8,10,110,165,119,165>>,
+ ?line Ebad = <<77>>,
+ ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
+ [sized_binary(E), sized_binary(N)]), true),
+ ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
+ [sized_binary(Ebad), sized_binary(N)]), false),
+ ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(SigBlob),
+ [sized_binary(E), sized_binary(Nbad)]), false),
+ ?line m(crypto:rsa_verify(sized_binary(H), sized_binary(BadSigBlob),
+ [sized_binary(E), sized_binary(N)]), false).
+
+%%
+%%
+dsa_verify_test(doc) ->
+ "dsa_verify testing (A ^ M % P with bignums)";
+dsa_verify_test(suite) ->
+ [];
+dsa_verify_test(Config) when is_list(Config) ->
+ ?line Msg = <<48,130,2,245,160,3,2,1,2,2,1,1,48,9,6,7,42,134,72,206,56,4,3,48,
+ 58,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3,85,4,10,19,17,
+ 84,101,115,116,32,67,101,114,116,105,102,105,99,97,116,101,115,49,
+ 15,48,13,6,3,85,4,3,19,6,68,83,65,32,67,65,48,30,23,13,48,49,48,
+ 52,49,57,49,52,53,55,50,48,90,23,13,49,49,48,52,49,57,49,52,53,55,
+ 50,48,90,48,93,49,11,48,9,6,3,85,4,6,19,2,85,83,49,26,48,24,6,3,
+ 85,4,10,19,17,84,101,115,116,32,67,101,114,116,105,102,105,99,97,
+ 116,101,115,49,50,48,48,6,3,85,4,3,19,41,86,97,108,105,100,32,68,
+ 83,65,32,83,105,103,110,97,116,117,114,101,115,32,69,69,32,67,101,
+ 114,116,105,102,105,99,97,116,101,32,84,101,115,116,52,48,130,1,
+ 182,48,130,1,43,6,7,42,134,72,206,56,4,1,48,130,1,30,2,129,129,0,
+ 228,139,175,64,140,21,215,61,124,238,3,150,18,104,193,32,5,232,23,
+ 202,158,116,101,75,154,84,151,42,120,51,218,165,197,114,234,52,
+ 179,148,104,66,213,27,253,119,240,168,66,158,100,147,144,182,194,
+ 2,49,70,19,122,3,105,204,152,45,86,157,94,35,95,40,191,173,127,15,
+ 208,105,149,98,92,26,7,42,94,140,115,73,126,253,18,34,142,85,229,
+ 86,233,174,114,41,150,135,8,39,215,119,67,240,134,184,9,10,27,20,
+ 165,230,3,230,69,121,77,233,250,83,95,193,9,189,126,197,195,2,21,
+ 0,128,63,228,252,243,76,229,62,203,15,23,10,42,84,108,208,103,108,
+ 13,59,2,129,128,102,212,22,138,32,173,254,209,50,159,165,127,167,
+ 179,208,234,119,63,235,108,162,228,41,216,216,188,33,221,154,247,
+ 204,229,180,119,77,223,236,218,162,140,156,117,18,90,31,254,102,
+ 211,17,194,239,132,67,236,169,136,110,76,186,76,63,53,150,199,103,
+ 252,153,189,15,153,41,19,145,78,216,2,174,254,107,175,80,86,170,
+ 47,30,181,42,200,238,34,71,37,120,107,33,221,20,63,206,240,16,129,
+ 247,150,29,156,65,187,94,68,146,93,46,198,30,184,205,105,200,143,
+ 63,59,62,208,79,162,206,217,3,129,132,0,2,129,128,15,83,40,172,56,
+ 47,61,243,17,97,65,195,61,167,214,122,247,246,1,50,211,33,113,16,
+ 20,213,195,62,77,235,25,162,140,175,158,8,61,65,10,255,204,162,71,
+ 130,122,86,161,163,253,236,178,139,183,57,181,202,160,25,133,130,
+ 155,150,104,168,187,107,186,144,164,225,173,101,182,68,49,210,30,
+ 34,47,83,65,79,250,156,248,47,232,44,67,36,22,126,43,216,100,247,
+ 100,250,240,121,72,29,185,2,109,144,54,204,235,54,15,242,57,171,
+ 125,39,236,247,71,111,221,51,196,126,77,238,36,87,163,107,48,105,
+ 48,29,6,3,85,29,14,4,22,4,20,179,51,215,81,162,4,13,68,251,157,64,
+ 241,18,98,113,176,83,246,105,13,48,31,6,3,85,29,35,4,24,48,22,128,
+ 20,116,21,213,36,28,189,94,101,136,31,225,139,9,126,127,234,25,72,
+ 78,97,48,23,6,3,85,29,32,4,16,48,14,48,12,6,10,96,134,72,1,101,3,
+ 2,1,48,1,48,14,6,3,85,29,15,1,1,255,4,4,3,2,6,192>>,
+
+ ?line SigBlob = <<48,45,2,21,0,140,167,200,210,153,212,64,155,249,33,146,104,243,
+ 39,38,9,115,162,89,24,2,20,76,254,31,128,187,48,128,215,216,
+ 112,198,78,118,160,217,157,180,246,64,234>>,
+ ?line P_p = 157224271412839155721795253728878055347359513988016145491388196653004661857517720927482198111104095793441029858267073789634147217022008635826863307553453131345099940951090826856271796188522037524757740796268675508118348391218066949174594918958269259937813776150149068811425194955973128428675945283593831134219,
+ ?line Q_p = 1181895316321540581845959276009400765315408342791,
+ ?line G_p = 143872196713149000950547166575757355261637863805587906227228163275557375159769599033632918292482002186641475268486598023281100659643528846513898847919251032731261718358900479488287933293278745715922865499005559197328388506945134386346185262919258658109015074718441639029135304654725637911172671711310801418648,
+
+ ?line Key = 12603618348903387232593303690286336220738319446775939686476278478034365380027994899970214309288018488811754534229198764622077544117034174589418477472887827980332636062691833965078594576024299807057520016043084384987871640003684704483975314128362610573625803532737054022545217931847268776098203204571431581966,
+
+ ValidKey = [crypto:mpint(P_p),
+ crypto:mpint(Q_p),
+ crypto:mpint(G_p),
+ crypto:mpint(Key)
+ ],
+
+ ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob),
+ ValidKey), true),
+
+ BadMsg = one_bit_wrong(Msg),
+ ?line m(crypto:dss_verify(sized_binary(BadMsg), sized_binary(SigBlob),
+ ValidKey), false),
+ BadSig = one_bit_wrong(SigBlob),
+ ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(BadSig),
+ ValidKey), false),
+ SizeErr = size(SigBlob) - 13,
+
+ BadArg = (catch crypto:dss_verify(sized_binary(Msg), <<SizeErr:32, SigBlob/binary>>,
+ ValidKey)),
+ ?line m(element(1,element(2,BadArg)), badarg),
+
+ InValidKey = [crypto:mpint(P_p),
+ crypto:mpint(Q_p),
+ crypto:mpint(G_p),
+ crypto:mpint(Key+17)
+ ],
+
+ ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(SigBlob),
+ InValidKey), false).
+
+one_bit_wrong(Bin) ->
+ Half = size(Bin) div 2,
+ <<First:Half/binary, Byte:8, Last/binary>> = Bin,
+ <<First/binary, (Byte+1):8, Last/binary>>.
+
+
+%%
+%% Sign tests
+
+rsa_sign_test(doc) ->
+ "rsa_sign testing";
+rsa_sign_test(suite) ->
+ [];
+rsa_sign_test(Config) when is_list(Config) ->
+ PubEx = 65537,
+ PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
+ Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
+ Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
+ "09812312908312378623487263487623412039812 huagasd">>,
+
+ PrivKey = [crypto:mpint(PubEx), crypto:mpint(Mod), crypto:mpint(PrivEx)],
+ PubKey = [crypto:mpint(PubEx), crypto:mpint(Mod)],
+ ?line Sig1 = crypto:rsa_sign(sized_binary(Msg), PrivKey),
+ ?line m(crypto:rsa_verify(sized_binary(Msg), sized_binary(Sig1),PubKey), true),
+
+ ?line Sig2 = crypto:rsa_sign(md5, sized_binary(Msg), PrivKey),
+ ?line m(crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig2),PubKey), true),
+
+ ?line m(Sig1 =:= Sig2, false),
+ ?line m(crypto:rsa_verify(md5, sized_binary(Msg), sized_binary(Sig1),PubKey), false),
+ ?line m(crypto:rsa_verify(sha, sized_binary(Msg), sized_binary(Sig1),PubKey), true),
+
+ ok.
+
+dsa_sign_test(doc) ->
+ "dsa_sign testing";
+dsa_sign_test(suite) ->
+ [];
+dsa_sign_test(Config) when is_list(Config) ->
+ Msg = <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
+ "09812312908312378623487263487623412039812 huagasd">>,
+
+ PubKey = _Y = 25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978,
+ PrivKey = _X = 441502407453038284293378221372000880210588566361,
+ ParamP = 109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797,
+ ParamQ = 1349199015905534965792122312016505075413456283393,
+ ParamG = 18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669,
+
+ Params = [crypto:mpint(ParamP), crypto:mpint(ParamQ), crypto:mpint(ParamG)],
+ ?line Sig1 = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PrivKey)]),
+
+ ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(Sig1),
+ [Params, crypto:mpint(PubKey)]), true),
+
+ ?line m(crypto:dss_verify(sized_binary(one_bit_wrong(Msg)), sized_binary(Sig1),
+ [Params, crypto:mpint(PubKey)]), false),
+
+ ?line m(crypto:dss_verify(sized_binary(Msg), sized_binary(one_bit_wrong(Sig1)),
+ [Params, crypto:mpint(PubKey)]), false),
+
+ %%?line Bad = crypto:dss_sign(sized_binary(Msg), [Params, crypto:mpint(PubKey)]),
+
+ ok.
+
+
+rsa_encrypt_decrypt(doc) ->
+ ["Test rsa_public_encrypt and rsa_private_decrypt functions."];
+rsa_encrypt_decrypt(suite) -> [];
+rsa_encrypt_decrypt(Config) when is_list(Config) ->
+ PubEx = 65537,
+ PrivEx = 7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945,
+ Mod = 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123,
+
+ PrivKey = [crypto:mpint(PubEx), crypto:mpint(Mod), crypto:mpint(PrivEx)],
+ PubKey = [crypto:mpint(PubEx), crypto:mpint(Mod)],
+
+ Msg = <<"7896345786348 Asldi">>,
+
+ ?line PKCS1 = crypto:rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_padding),
+ ?line PKCS1Dec = crypto:rsa_private_decrypt(PKCS1, PrivKey, rsa_pkcs1_padding),
+ io:format("PKCS1Dec ~p~n",[PKCS1Dec]),
+ ?line Msg = PKCS1Dec,
+
+ ?line OAEP = crypto:rsa_public_encrypt(Msg, PubKey, rsa_pkcs1_oaep_padding),
+ ?line Msg = crypto:rsa_private_decrypt(OAEP, PrivKey, rsa_pkcs1_oaep_padding),
+
+ <<Msg2Len:32,_/binary>> = crypto:mpint(Mod),
+ Msg2 = list_to_binary(lists:duplicate(Msg2Len-1, $X)),
+ ?line NoPad = crypto:rsa_public_encrypt(Msg2, PubKey, rsa_no_padding),
+ ?line NoPadDec = crypto:rsa_private_decrypt(NoPad, PrivKey, rsa_no_padding),
+ ?line NoPadDec = Msg2,
+
+ ShouldBeError = (catch crypto:rsa_public_encrypt(Msg, PubKey, rsa_no_padding)),
+ ?line {'EXIT', {encrypt_failed,_}} = ShouldBeError,
+
+%% ?line SSL = crypto:rsa_public_encrypt(Msg, PubKey, rsa_sslv23_padding),
+%% ?line Msg = crypto:rsa_private_decrypt(SSL, PrivKey, rsa_sslv23_padding),
+
+ ?line PKCS1_2 = crypto:rsa_private_encrypt(Msg, PrivKey, rsa_pkcs1_padding),
+ ?line PKCS1_2Dec = crypto:rsa_public_decrypt(PKCS1_2, PubKey, rsa_pkcs1_padding),
+ io:format("PKCS2Dec ~p~n",[PKCS1_2Dec]),
+ ?line Msg = PKCS1_2Dec,
+
+ ?line PKCS1_3 = crypto:rsa_private_encrypt(Msg2, PrivKey, rsa_no_padding),
+ ?line PKCS1_3Dec = crypto:rsa_public_decrypt(PKCS1_3, PubKey, rsa_no_padding),
+ io:format("PKCS2Dec ~p~n",[PKCS1_3Dec]),
+ ?line Msg2 = PKCS1_3Dec,
+
+ ?line {'EXIT', {encrypt_failed,_}} =
+ (catch crypto:rsa_private_encrypt(Msg, PrivKey, rsa_no_padding)),
+
+ ok.
+
+
+dh(doc) ->
+ ["Test dh (Diffie-Hellman) functions."];
+dh(suite) -> [];
+dh(Config) when is_list(Config) ->
+ Self = self(),
+ GenP = fun() ->
+ %% Gen Param may take arbitrary long time to finish
+ %% That's not a bug in erlang crypto application.
+ ?line DHPs = crypto:dh_generate_parameters(512,2),
+ ?line ok = crypto:dh_check(DHPs),
+ Self ! {param, DHPs}
+ end,
+ Pid = spawn(GenP),
+ receive
+ {param, DHPs} ->
+ timer:sleep(100),
+ io:format("DHP ~p~n", [DHPs]),
+ ?line {Pub1,Priv1} = crypto:dh_generate_key(DHPs),
+ io:format("Key1:~n~p~n~p~n~n", [Pub1,Priv1]),
+ ?line {Pub2,Priv2} = crypto:dh_generate_key(DHPs),
+ io:format("Key2:~n~p~n~p~n~n", [Pub2,Priv2]),
+ ?line A = crypto:dh_compute_key(Pub1, Priv2, DHPs),
+ timer:sleep(100), %% Get another thread see if that triggers problem
+ ?line B = crypto:dh_compute_key(Pub2, Priv1, DHPs),
+ io:format("A ~p~n",[A]),
+ io:format("B ~p~n",[B]),
+ ?line A = B
+ after 50000 ->
+ io:format("Killing Param generation which took to long ~p~n",[Pid]),
+ exit(Pid, kill)
+ end.
+
+%%
+%%
+exor_test(doc) ->
+ ["Test the exor function."];
+exor_test(suite) ->
+ [];
+exor_test(Config) when is_list(Config) ->
+ B = <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>,
+ Z1 = zero_bin(B),
+ Z1 = crypto:exor(B, B),
+ B1 = crypto:rand_bytes(100),
+ B2 = crypto:rand_bytes(100),
+ Z2 = zero_bin(B1),
+ Z2 = crypto:exor(B1, B1),
+ Z2 = crypto:exor(B2, B2),
+ R = xor_bytes(B1, B2),
+ R = crypto:exor(B1, B2),
+ ok.
+
+%%
+%%
+rc4_test(doc) ->
+ ["Test rc4 encryption ."];
+rc4_test(suite) ->
+ [];
+rc4_test(Config) when is_list(Config) ->
+ CT1 = <<"hej p� dig">>,
+ R1 = <<71,112,14,44,140,33,212,144,155,47>>,
+ K = "apaapa",
+ R1 = crypto:rc4_encrypt(K, CT1),
+ CT1 = crypto:rc4_encrypt(K, R1),
+ CT2 = lists:seq(0, 255),
+ R2 = crypto:rc4_encrypt(K, CT2),
+ CT2 = binary_to_list(crypto:rc4_encrypt(K, R2)),
+ ok.
+
+blowfish_cfb64(doc) -> ["Test Blowfish encrypt/decrypt."];
+blowfish_cfb64(suite) -> [];
+blowfish_cfb64(Config) when is_list(Config) ->
+ Key = <<1,35,69,103,137,171,205,239,240,225,210,195,180,165,150,135>>,
+
+ IVec = <<254,220,186,152,118,84,50,16>>,
+ Plain = <<"7654321 Now is the time for ">>,
+ Enc = <<231,50,20,162,130,33,57,202,242,110,207,109,46,185,231,110,61,163,222,4,209,81,114,0,81,157,87,166>>,
+
+ Enc = crypto:blowfish_cfb64_encrypt(Key, IVec, Plain),
+ Plain = crypto:blowfish_cfb64_decrypt(Key, IVec, Enc),
+
+ Key2 = <<"A2B4C">>,
+ IVec2 = <<"12345678">>,
+ Plain2 = <<"badger at my table....!">>,
+ Enc2 = <<173,76,128,155,70,81,79,228,4,162,188,92,119,53,144,89,93,236,28,164,176,16,138>>,
+
+ Enc2 = crypto:blowfish_cfb64_encrypt(Key2, IVec2, Plain2),
+ Plain2 = crypto:blowfish_cfb64_decrypt(Key2, IVec2, Enc2).
+
+
+smp(doc) -> "Check concurrent access to crypto driver";
+smp(suite) -> [];
+smp(Config) ->
+ case erlang:system_info(smp_support) of
+ true ->
+ NumOfProcs = erlang:system_info(schedulers),
+ io:format("smp starting ~p workers\n",[NumOfProcs]),
+ Seeds = [random:uniform(9999) || _ <- lists:seq(1,NumOfProcs)],
+ Parent = self(),
+ Pids = [spawn_link(fun()-> worker(Seed,Config,Parent) end)
+ || Seed <- Seeds],
+ wait_pids(Pids);
+
+ false ->
+ {skipped,"No smp support"}
+ end.
+
+worker(Seed, Config, Parent) ->
+ io:format("smp worker ~p, seed=~p~n",[self(),Seed]),
+ random:seed(Seed,Seed,Seed),
+ worker_loop(100, Config),
+ %%io:format("worker ~p done\n",[self()]),
+ Parent ! self().
+
+worker_loop(0, _) ->
+ ok;
+worker_loop(N, Config) ->
+ Funcs = { md5, md5_update, md5_mac, md5_mac_io, sha, sha_update, des_cbc,
+ aes_cfb, aes_cbc, des_cbc_iter, rand_uniform_test,
+ rsa_verify_test, exor_test, rc4_test, mod_exp_test },
+
+ F = element(random:uniform(size(Funcs)),Funcs),
+ %%io:format("worker ~p calling ~p\n",[self(),F]),
+ ?MODULE:F(Config),
+ worker_loop(N-1,Config).
+
+wait_pids([]) ->
+ ok;
+wait_pids(Pids) ->
+ receive
+ Pid ->
+ ?line true = lists:member(Pid,Pids),
+ Others = lists:delete(Pid,Pids),
+ io:format("wait_pid got ~p, still waiting for ~p\n",[Pid,Others]),
+ wait_pids(Others)
+ end.
+
+%%
+%% Help functions
+%%
+
+% match
+m(X, X) ->
+ ?line true.
+t(true) ->
+ true.
+
+% hexstr2bin
+hexstr2bin(S) ->
+ list_to_binary(hexstr2list(S)).
+
+hexstr2list([X,Y|T]) ->
+ [mkint(X)*16 + mkint(Y) | hexstr2list(T)];
+hexstr2list([]) ->
+ [].
+
+mkint(C) when $0 =< C, C =< $9 ->
+ C - $0;
+mkint(C) when $A =< C, C =< $F ->
+ C - $A + 10;
+mkint(C) when $a =< C, C =< $f ->
+ C - $a + 10.
+
+%% mod_exp in erlang (copied from jungerl's ssh_math.erl)
+ipow(A, B, M) when M > 0, B >= 0 ->
+ if A == 1 ->
+ 1;
+ true ->
+ ipow(A, B, M, 1)
+ end.
+
+ipow(A, 1, M, Prod) ->
+ (A*Prod) rem M;
+ipow(_A, 0, _M, Prod) ->
+ Prod;
+ipow(A, B, M, Prod) ->
+ B1 = B bsr 1,
+ A1 = (A*A) rem M,
+ if B - B1 == B1 ->
+ ipow(A1, B1, M, Prod);
+ true ->
+ ipow(A1, B1, M, (A*Prod) rem M)
+ end.
+
+%%
+%% Invert an element X mod P
+%% Calculated as {1, {A,B}} = egcd(X,P),
+%% 1 == P*A + X*B == X*B (mod P) i.e B is the inverse element
+%%
+%% X > 0, P > 0, X < P (P should be prime)
+%%
+%% invert(X,P) when X > 0, P > 0, X < P ->
+%% I = inv(X,P,1,0),
+%% if
+%% I < 0 -> P + I;
+%% true -> I
+%% end.
+
+%% inv(0,_,_,Q) -> Q;
+%% inv(X,P,R1,Q1) ->
+%% D = P div X,
+%% inv(P rem X, X, Q1 - D*R1, R1).
+
+sized_binary(Binary) when is_binary(Binary) ->
+ <<(size(Binary)):32/integer, Binary/binary>>;
+sized_binary(List) ->
+ sized_binary(list_to_binary(List)).
+
+xor_bytes(Bin1, Bin2) when is_binary(Bin1), is_binary(Bin2) ->
+ L1 = binary_to_list(Bin1),
+ L2 = binary_to_list(Bin2),
+ list_to_binary(xor_bytes(L1, L2));
+xor_bytes(L1, L2) ->
+ xor_bytes(L1, L2, []).
+
+xor_bytes([], [], Acc) ->
+ lists:reverse(Acc);
+xor_bytes([N1 | Tl1], [N2 | Tl2], Acc) ->
+ xor_bytes(Tl1, Tl2, [N1 bxor N2 | Acc]).
+
+zero_bin(N) when is_integer(N) ->
+ N8 = N * 8,
+ <<0:N8/integer>>;
+zero_bin(B) when is_binary(B) ->
+ zero_bin(size(B)).
diff --git a/lib/debugger/doc/src/Makefile b/lib/debugger/doc/src/Makefile
index e6a1de2701..1c0bbaf9d2 100644
--- a/lib/debugger/doc/src/Makefile
+++ b/lib/debugger/doc/src/Makefile
@@ -39,7 +39,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/$(APPLICATION)-$(VSN)
XML_APPLICATION_FILES = ref_man.xml
XML_REF3_FILES = debugger.xml i.xml int.xml
-XML_PART_FILES = part.xml part_notes.xml
+XML_PART_FILES = part.xml
XML_CHAPTER_FILES = debugger_chapter.xml notes.xml
BOOK_FILES = book.xml
diff --git a/lib/debugger/doc/src/part_notes.xml b/lib/debugger/doc/src/part_notes.xml
deleted file mode 100644
index 60299bbb11..0000000000
--- a/lib/debugger/doc/src/part_notes.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part xmlns:xi="http://www.w3.org/2001/XInclude">
- <header>
- <copyright>
- <year>2004</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Debugger Release Notes</title>
- <prepared></prepared>
- <docno></docno>
- <date>2004-09-07</date>
- <rev>1.0</rev>
- <file>part_notes.sgml</file>
- </header>
- <description>
- <p><em>Debugger</em> is a graphical tool which can be used for
- debugging and testing of Erlang programs. For example, breakpoints
- can be set, code can be single stepped and variable values can be
- displayed and changed.</p>
- </description>
- <xi:include href="notes.xml">
-</part>
-
-
diff --git a/lib/debugger/doc/src/warning.gif b/lib/debugger/doc/src/warning.gif
deleted file mode 100644
index 96af52360e..0000000000
--- a/lib/debugger/doc/src/warning.gif
+++ /dev/null
Binary files differ
diff --git a/lib/debugger/src/dbg_ui_mon.erl b/lib/debugger/src/dbg_ui_mon.erl
index 63cc9b66d1..8888075124 100644
--- a/lib/debugger/src/dbg_ui_mon.erl
+++ b/lib/debugger/src/dbg_ui_mon.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-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(dbg_ui_mon).
@@ -429,8 +429,7 @@ gui_cmd('Back Trace Size...', State) ->
%% Help Menu
gui_cmd('Debugger', State) ->
- HelpFile = filename:join([code:lib_dir(debugger),
- "doc", "html", "part_frame.html"]),
+ HelpFile = filename:join([code:lib_dir(debugger), "doc", "html", "index.html"]),
Window = dbg_ui_mon_win:get_window(State#state.win),
tool_utils:open_help(Window, HelpFile),
State;
diff --git a/lib/debugger/src/dbg_wx_filedialog_win.erl b/lib/debugger/src/dbg_wx_filedialog_win.erl
index d883438639..9687efa981 100644
--- a/lib/debugger/src/dbg_wx_filedialog_win.erl
+++ b/lib/debugger/src/dbg_wx_filedialog_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2009-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(dbg_wx_filedialog_win).
@@ -375,7 +375,8 @@ show_completion(Wanted, State = #state{text=TC, win=Win, list=LC, completion=Com
Start = length(Wanted),
wxTextCtrl:setValue(TC, Path++"/"),
wxTextCtrl:setInsertionPoint(TC, Start),
- wxTextCtrl:setSelection(TC, Start, -1),
+ Last = wxTextCtrl:getLastPosition(TC),
+ wxTextCtrl:setSelection(TC, Start, Last),
destroy_completion(Comp),
wxWindow:setFocus(TC),
State#state{ptext=Path, completion=undefined};
@@ -399,7 +400,7 @@ show_completion(Wanted, State = #state{text=TC, win=Win, list=LC, completion=Com
LB = wxListBox:new(Temp, ?COMPLETION_WIN,
[{style, ?wxLB_SINGLE}, {choices, Files}, {size, Size}]),
- wxListBox:connect(LB, command_listbox_doubleclicked),
+ %% wxListBox:connect(LB, command_listbox_doubleclicked),
wxListBox:connect(LB, command_listbox_selected),
wxWindow:show(Temp),
wxWindow:setFocus(TC),
diff --git a/lib/debugger/src/dbg_wx_mon.erl b/lib/debugger/src/dbg_wx_mon.erl
index d81069ec90..3f55c38d35 100644
--- a/lib/debugger/src/dbg_wx_mon.erl
+++ b/lib/debugger/src/dbg_wx_mon.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% 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%
%%
@@ -144,7 +144,7 @@ init2(CallingPid, Mode, SFile, GS) ->
win = Win,
focus = undefined,
- coords = {0,0},
+ coords = {20,20},
intdir = element(2, file:get_cwd()),
pinfos = [],
@@ -442,8 +442,7 @@ gui_cmd('Back Trace Size...', State) ->
%% Help Menu
gui_cmd('Debugger', State) ->
- HelpFile = filename:join([code:lib_dir(debugger),
- "doc", "html", "part_frame.html"]),
+ HelpFile = filename:join([code:lib_dir(debugger), "doc", "html", "index.html"]),
Window = dbg_wx_mon_win:get_window(State#state.win),
dbg_wx_win:open_help(Window, HelpFile),
State;
diff --git a/lib/debugger/src/dbg_wx_mon_win.erl b/lib/debugger/src/dbg_wx_mon_win.erl
index dfb327fa6a..8ad4f4213f 100644
--- a/lib/debugger/src/dbg_wx_mon_win.erl
+++ b/lib/debugger/src/dbg_wx_mon_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% 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%
%%
@@ -104,7 +104,7 @@ create_win_batch(Title, Menus) ->
Hlb = 200,
Listbox = wxListBox:new(Panel, ?wxID_ANY, [{size,{?Wf,Hlb}},
{style,?wxLB_SINGLE}]),
- wxSizer:add(LeftSz,Listbox,[{border, 3}]),
+ wxSizer:add(LeftSz,Listbox,[{proportion,1}, {border,3}]),
wxListBox:connect(Listbox, command_listbox_doubleclicked),
wxListBox:connect(Listbox, right_down),
diff --git a/lib/debugger/src/dbg_wx_trace_win.erl b/lib/debugger/src/dbg_wx_trace_win.erl
index 6e7a291493..3799acdc1b 100755
--- a/lib/debugger/src/dbg_wx_trace_win.erl
+++ b/lib/debugger/src/dbg_wx_trace_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% 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%
%%
@@ -571,7 +571,7 @@ update_bindings(#winInfo{bind=#sub{out=BA}}, Bs) ->
wx:foldl(fun({Var,Val},Row) ->
wxListCtrl:insertItem(BA, Row, ""),
wxListCtrl:setItem(BA, Row, 0, dbg_wx_win:to_string(Var)),
- wxListCtrl:setItem(BA, Row, 1, dbg_wx_win:to_string("~200p",[Val])),
+ wxListCtrl:setItem(BA, Row, 1, dbg_wx_win:to_string("~500P",[Val, 80])),
Row+1
end, 0, Bs),
put(bindings,Bs),
diff --git a/lib/debugger/src/dbg_wx_win.erl b/lib/debugger/src/dbg_wx_win.erl
index f029990aa4..faf3cc178f 100644
--- a/lib/debugger/src/dbg_wx_win.erl
+++ b/lib/debugger/src/dbg_wx_win.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% 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%
%%
@@ -75,7 +75,8 @@ create_menus(MB, [{Title,Items}|Ms], Win, Id0) ->
Id = create_menu_item(Menu, Items, Win, Id0, true),
wxMenuBar:append(MB,Menu,menu_name(Title,ignore)),
create_menus(MB,Ms,Win,Id);
-create_menus(_MB,[], _Win,Id) -> Id.
+create_menus(_MB,[], _Win,Id) ->
+ Id.
create_menu_item(Menu, [separator|Is], Win, Id,Connect) ->
wxMenu:appendSeparator(Menu),
@@ -102,10 +103,14 @@ create_menu_item(Menu, [{Name, _N, cascade, Items}|Is], Win, Id0,Connect) ->
[{id,Id0},{lastId, Id-1},{callback,Filter}]),
create_menu_item(Menu, Is, Win, Id, Connect);
create_menu_item(Menu, [{Name,Pos}|Is], Win, Id, Connect) ->
- Item = wxMenu:append(Menu, Id, menu_name(Name,Pos)),
+ MenuId = case lists:member(Name, ['Debugger']) of
+ true -> ?wxID_HELP;
+ _ -> Id
+ end,
+ Item = wxMenu:append(Menu, MenuId, menu_name(Name,Pos)),
put(Name,Item),
if Connect ->
- wxMenu:connect(Win, command_menu_selected, [{id,Id},{userData, Name}]);
+ wxMenu:connect(Win, command_menu_selected, [{id,MenuId},{userData, Name}]);
true -> ignore
end,
create_menu_item(Menu,Is,Win,Id+1, Connect);
@@ -308,6 +313,8 @@ to_string(Format,Args) ->
menu_name(Atom, N) when is_atom(Atom) ->
menu_name(atom_to_list(Atom),N);
+menu_name("Help", _) -> %% Mac needs this to be exactly this
+ "&Help";
menu_name(Str, Pos) when is_integer(Pos) ->
{S1,S2} = lists:split(Pos,Str),
S1 ++ [$&|S2];
diff --git a/lib/erl_docgen/priv/xsl/db_eix.xsl b/lib/erl_docgen/priv/xsl/db_eix.xsl
new file mode 100644
index 0000000000..929272256a
--- /dev/null
+++ b/lib/erl_docgen/priv/xsl/db_eix.xsl
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ #
+ # %CopyrightBegin%
+ #
+ # Copyright Ericsson AB 2009. All Rights Reserved.
+ #
+ # The contents of this file are subject to the Erlang Public License,
+ # Version 1.1, (the "License"); you may not use this file except in
+ # compliance with the License. You should have received a copy of the
+ # Erlang Public License along with this software. If not, it can be
+ # retrieved online at http://www.erlang.org/.
+ #
+ # Software distributed under the License is distributed on an "AS IS"
+ # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ # the License for the specific language governing rights and limitations
+ # under the License.
+ #
+ # %CopyrightEnd%
+
+ -->
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:fn="http://www.w3.org/2005/02/xpath-functions">
+
+ <xsl:output method="text" encoding="UTF-8" indent="no"/>
+
+ <!-- Book -->
+ <xsl:template match="/book">
+ <xsl:text>%% &#10;%% Search data file for </xsl:text><xsl:value-of select="$appname"/><xsl:text> </xsl:text><xsl:value-of select="$appver"/>
+ <xsl:text>&#10;%% generated </xsl:text><xsl:value-of select="$gendate"/><xsl:text>&#10;%% &#10;</xsl:text>
+ <xsl:apply-templates select="applications"/>
+ <xsl:text>{notused, application, ["</xsl:text><xsl:value-of select="$appname"/><xsl:text>"]}.&#10;</xsl:text>
+ </xsl:template>
+
+ <!-- Applications -->
+ <xsl:template match="applications">
+ <xsl:apply-templates name="application"/>
+ </xsl:template>
+
+ <!-- Reference Manual -->
+
+ <!-- Application -->
+ <xsl:template match="application">
+ <xsl:apply-templates select="erlref|cref|comref|fileref|appref"/>
+ </xsl:template>
+
+ <!-- Erlref -->
+ <xsl:template match="erlref">
+ <xsl:text>{"</xsl:text><xsl:value-of select="module"/><xsl:text>.html", {function, {"</xsl:text><xsl:value-of select="$appname"/>
+ <xsl:text>", "</xsl:text><xsl:value-of select="module"/><xsl:text>"}},&#10;[&#10;</xsl:text>
+ <xsl:apply-templates select="funcs">
+ <xsl:with-param name="mod" select="module"/>
+ </xsl:apply-templates>
+ <xsl:text>]}.&#10;</xsl:text>
+ <xsl:text>{"</xsl:text><xsl:value-of select="module"/><xsl:text>.html", {module, "</xsl:text>
+ <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="module"/><xsl:text>"]}.&#10;</xsl:text>
+ </xsl:template>
+
+ <!-- Cref -->
+ <xsl:template match="cref">
+ <xsl:text>{"</xsl:text><xsl:value-of select="lib"/><xsl:text>.html", {function, {"</xsl:text><xsl:value-of select="$appname"/>
+ <xsl:text>", "</xsl:text><xsl:value-of select="lib"/><xsl:text>"}}, [&#10;</xsl:text>
+ <xsl:apply-templates select="funcs">
+ <xsl:with-param name="mod" select="lib"/>
+ </xsl:apply-templates>
+ <xsl:text>]}.&#10;</xsl:text>
+ <xsl:text>{"</xsl:text><xsl:value-of select="lib"/><xsl:text>.html", {clib, "</xsl:text>
+ <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="lib"/><xsl:text>"]}.&#10;</xsl:text>
+ </xsl:template>
+
+ <!-- Comref -->
+ <xsl:template match="comref">
+ <xsl:text>{"</xsl:text><xsl:value-of select="com"/><xsl:text>.html", {command, "</xsl:text>
+ <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="com"/><xsl:text>"]}.&#10;</xsl:text>
+ </xsl:template>
+
+ <!-- Fileref -->
+ <xsl:template match="fileref">
+ <xsl:text>{"</xsl:text><xsl:value-of select="file"/><xsl:text>.html", {file, "</xsl:text>
+ <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="file"/><xsl:text>"]}.&#10;</xsl:text>
+ </xsl:template>
+
+ <!-- Appref -->
+ <xsl:template match="appref">
+ <xsl:text>{"</xsl:text><xsl:value-of select="app"/><xsl:text>_app.html", {app, "</xsl:text>
+ <xsl:value-of select="$appname"/><xsl:text>"}, ["</xsl:text><xsl:value-of select="app"/><xsl:text>"]}.&#10;</xsl:text>
+ </xsl:template>
+
+
+ <!-- Funcs -->
+ <xsl:template match="funcs">
+ <xsl:param name="mod"/>
+ <xsl:variable name="lastfuncsblock">
+ <xsl:value-of select="position() = last()"/>
+ </xsl:variable>
+ <xsl:apply-templates select="func/name">
+ <xsl:with-param name="mod" select="$mod"/>
+ <xsl:with-param name="lastfuncsblock" select="$lastfuncsblock"/>
+ </xsl:apply-templates>
+ </xsl:template>
+
+
+
+
+ <xsl:template match="name">
+ <xsl:param name="mod"/>
+ <xsl:param name="lastfuncsblock"/>
+
+ <xsl:variable name="tmpstring">
+ <xsl:value-of select="substring-before(substring-after(., '('), '->')"/>
+ </xsl:variable>
+ <xsl:variable name="ustring">
+ <xsl:choose>
+ <xsl:when test="string-length($tmpstring) > 0">
+ <xsl:call-template name="remove-paren">
+ <xsl:with-param name="string" select="$tmpstring"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:call-template name="remove-paren">
+ <xsl:with-param name="string" select="substring-after(., '(')"/>
+ </xsl:call-template>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:variable name="arity">
+ <xsl:call-template name="calc-arity">
+ <xsl:with-param name="string" select="substring-before($ustring, ')')"/>
+ <xsl:with-param name="no-of-pars" select="0"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="fname">
+ <xsl:choose>
+ <xsl:when test="ancestor::cref">
+ <xsl:value-of select="substring-before(nametext, '(')"/>
+ </xsl:when>
+ <xsl:when test="ancestor::erlref">
+ <xsl:value-of select="substring-before(., '(')"/>
+ </xsl:when>
+ </xsl:choose>
+ </xsl:variable>
+ <xsl:text> {"</xsl:text><xsl:value-of select="$fname"/>
+ <xsl:text>", "</xsl:text><xsl:value-of select="$fname"/>
+ <xsl:text>(</xsl:text><xsl:value-of select="normalize-space($tmpstring)"/>
+ <xsl:text>", "</xsl:text><xsl:value-of select="$fname"/>
+ <xsl:text>-</xsl:text><xsl:value-of select="$arity"/><xsl:text>"}</xsl:text>
+
+ <xsl:choose>
+ <xsl:when test="($lastfuncsblock = 'true') and (position() = last())">
+ <xsl:text>&#10;</xsl:text>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:text>,&#10;</xsl:text>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Special templates to calculate the arity of functions -->
+ <xsl:template name="calc-arity">
+ <xsl:param name="string"/>
+ <xsl:param name="no-of-pars"/>
+ <xsl:variable name="length">
+ <xsl:value-of select="string-length($string)"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="$length > 0">
+ <xsl:call-template name="calc-arity">
+ <xsl:with-param name="string" select="substring-after($string, ',')"/>
+ <xsl:with-param name="no-of-pars" select="$no-of-pars+1"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$no-of-pars"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <xsl:template name="remove-paren">
+ <xsl:param name="string"/>
+ <xsl:variable name="bstring">
+ <xsl:value-of select="substring-before($string, '(')"/>
+ </xsl:variable>
+ <xsl:choose>
+ <xsl:when test="string-length($bstring) > 0">
+ <xsl:variable name="astring">
+ <xsl:value-of select="substring-after($string, ')')"/>
+ </xsl:variable>
+ <xsl:variable name="retstring">
+ <xsl:call-template name="remove-paren">
+ <xsl:with-param name="string" select="$astring"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:value-of select="concat($bstring, $retstring)"/>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:value-of select="$string"/>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- default content handling -->
+ <xsl:template match="text()"/>
+
+</xsl:stylesheet>
diff --git a/lib/erl_docgen/priv/xsl/db_html.xsl b/lib/erl_docgen/priv/xsl/db_html.xsl
index 3e6f762870..984655fc26 100644
--- a/lib/erl_docgen/priv/xsl/db_html.xsl
+++ b/lib/erl_docgen/priv/xsl/db_html.xsl
@@ -61,7 +61,7 @@
<xsl:value-of select="$copyright"/>
<xsl:value-of select="/book/header/copyright/year[1]"/>
<xsl:text>-</xsl:text>
- <xsl:value-of select="substring-after(substring-after($gendate, ' '), ' ')"/>
+ <xsl:value-of select="substring-after(normalize-space(substring-after($gendate, ' ')), ' ')"/>
<xsl:text> </xsl:text>
<xsl:value-of select="/book/header/copyright/holder"/>
</p>
diff --git a/lib/erl_interface/configure.in b/lib/erl_interface/configure.in
index 80b229c1c3..2f5b5673bb 100644
--- a/lib/erl_interface/configure.in
+++ b/lib/erl_interface/configure.in
@@ -100,11 +100,11 @@ if test "x$LD" = "x"; then
fi
AC_SUBST(LD)
-AC_CHECK_SIZEOF(short, $erl_xcomp_short)
-AC_CHECK_SIZEOF(int, $erl_xcomp_int)
-AC_CHECK_SIZEOF(long, $erl_xcomp_long)
-AC_CHECK_SIZEOF(void *, $erl_xcomp_void_p)
-AC_CHECK_SIZEOF(long long, $erl_xcomp_long_long)
+AC_CHECK_SIZEOF(short)
+AC_CHECK_SIZEOF(int)
+AC_CHECK_SIZEOF(long)
+AC_CHECK_SIZEOF(void *)
+AC_CHECK_SIZEOF(long long)
if test $ac_cv_sizeof_void_p = 8; then
CFLAGS="$CFLAGS -DEI_64BIT"
diff --git a/lib/erl_interface/doc/src/ei_connect.xml b/lib/erl_interface/doc/src/ei_connect.xml
index 08e7b122c6..abf705f9e2 100644
--- a/lib/erl_interface/doc/src/ei_connect.xml
+++ b/lib/erl_interface/doc/src/ei_connect.xml
@@ -619,6 +619,16 @@ typedef struct {
<p>These are convenience functions for some common name lookup functions.</p>
</desc>
</func>
+ <func>
+ <name><ret>int</ret><nametext>ei_get_tracelevel(void)</nametext></name>
+ <name><ret>void</ret><nametext>ei_set_tracelevel(int level)</nametext></name>
+ <fsummary>Get and set functions for tracing.</fsummary>
+ <desc>
+ <p>These functions are used to set tracing on the distribution. The levels are different verbosity levels. A higher level means more information.
+ See also Debug Information and <c><![CDATA[EI_TRACELEVEL]]></c> below. </p>
+ <p> <c><![CDATA[ei_set_tracelevel]]></c> and <c><![CDATA[ei_get_tracelevel]]></c> are not thread safe. </p>
+ </desc>
+ </func>
</funcs>
<section>
@@ -634,6 +644,17 @@ typedef struct {
<item>the environment variable <c><![CDATA[ERL_EPMD_PORT]]></c>
is set correctly.</item>
</list>
+ <p>The connection attempt can be traced by setting a tracelevel by either using
+ <c><![CDATA[ei_set_tracelevel]]></c> or by setting the environment variable <c><![CDATA[EI_TRACELEVEL]]></c>.
+ The different tracelevels has the following messages:</p>
+ <list>
+ <item>1: Verbose error messages</item>
+ <item>2: Above messages and verbose warning messages </item>
+ <item>3: Above messages and progress reports for connection handling</item>
+ <item>4: Above messages and progress reports for communication</item>
+ <item>5: Above messages and progress reports for data conversion</item>
+ </list>
</section>
+
</cref>
diff --git a/lib/erl_interface/include/ei.h b/lib/erl_interface/include/ei.h
index 01272244e1..d1a697615a 100644
--- a/lib/erl_interface/include/ei.h
+++ b/lib/erl_interface/include/ei.h
@@ -339,7 +339,13 @@ const char *ei_thisalivename(const ei_cnode* ec);
erlang_pid *ei_self(ei_cnode* ec);
+/*
+ * settings
+ */
+
void ei_set_compat_rel(unsigned rel);
+void ei_set_tracelevel(int);
+int ei_get_tracelevel(void);
/*
* We have erl_gethost*() so we include ei versions as well.
diff --git a/lib/erl_interface/src/connect/ei_connect.c b/lib/erl_interface/src/connect/ei_connect.c
index 9ac5a93c5a..d2d0a7e7c1 100644
--- a/lib/erl_interface/src/connect/ei_connect.c
+++ b/lib/erl_interface/src/connect/ei_connect.c
@@ -249,8 +249,22 @@ ei_cnode *ei_fd_to_cnode(int fd)
return &sockinfo->cnode;
}
+
+/***************************************************************************
+ * Get/Set tracelevel
+ ***************************************************************************/
+
+void ei_set_tracelevel(int level) {
+ ei_tracelevel = level;
+}
+
+int ei_get_tracelevel(void) {
+ return ei_tracelevel;
+}
+
+
/***************************************************************************
- * XXXX
+ * Distversion
***************************************************************************/
int ei_distversion(int fd)
@@ -1282,8 +1296,6 @@ error:
return -1;
}
-/* FIXME fix the signed/unsigned mess..... */
-
static int send_name_or_challenge(int fd, char *nodename,
int f_chall,
unsigned challenge,
diff --git a/lib/erl_interface/src/decode/decode_skip.c b/lib/erl_interface/src/decode/decode_skip.c
index 2fc68a3601..316b5bee98 100644
--- a/lib/erl_interface/src/decode/decode_skip.c
+++ b/lib/erl_interface/src/decode/decode_skip.c
@@ -80,6 +80,7 @@ int ei_skip_term(const char* buf, int* index)
if (ei_decode_double(buf, index, NULL) < 0) return -1;
break;
case ERL_FUN_EXT:
+ case ERL_NEW_FUN_EXT:
if (ei_decode_fun(buf, index, NULL) < 0) return -1;
break;
default:
diff --git a/lib/erl_interface/src/misc/ei_internal.h b/lib/erl_interface/src/misc/ei_internal.h
index 9f51d1f61b..f7805efebf 100644
--- a/lib/erl_interface/src/misc/ei_internal.h
+++ b/lib/erl_interface/src/misc/ei_internal.h
@@ -149,7 +149,7 @@
{if (ei_tracelevel >= 5) ei_trace_printf(NAME,1,FORMAT,ARG1,ARG2,ARG3,ARG4, \
ARG5,ARG6,ARG7);}
-int ei_tracelevel;
+extern int ei_tracelevel;
void ei_trace_printf(const char *name, int level, const char *format, ...);
diff --git a/lib/erl_interface/test/Makefile b/lib/erl_interface/test/Makefile
new file mode 100644
index 0000000000..b7a1a4e4d8
--- /dev/null
+++ b/lib/erl_interface/test/Makefile
@@ -0,0 +1,78 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include $(ERL_TOP)/make/target.mk
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ ei_accept_SUITE \
+ ei_connect_SUITE \
+ ei_decode_SUITE \
+ ei_decode_encode_SUITE \
+ ei_encode_SUITE \
+ ei_format_SUITE \
+ ei_print_SUITE \
+ ei_tmo_SUITE \
+ erl_connect_SUITE \
+ erl_eterm_SUITE \
+ erl_ext_SUITE \
+ erl_format_SUITE \
+ erl_match_SUITE \
+ port_call_SUITE \
+ runner
+
+SPEC_FILES = \
+ erl_interface.spec \
+ erl_interface.dynspec \
+ erl_interface.spec.vxworks
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/erl_interface_test
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+tests debug opt:
+
+clean:
+
+docs:
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec:
+
+release_tests_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(RELSYSDIR)
+ chmod -f -R u+w $(RELSYSDIR)
+ @tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
+
+release_docs_spec:
diff --git a/lib/erl_interface/test/Makefile.src b/lib/erl_interface/test/Makefile.src
new file mode 100644
index 0000000000..9c620bb8d9
--- /dev/null
+++ b/lib/erl_interface/test/Makefile.src
@@ -0,0 +1,71 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = $(LIBERL) $(LIBEI)
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../common
+
+ETERM_OBJS = eterm_test@obj@ eterm_test_decl@obj@ runner@obj@
+EXT_OBJS = ext_test@obj@ ext_test_decl@obj@ runner@obj@
+FORMAT_OBJS = format_test@obj@ format_test_decl@obj@ runner@obj@
+EI_FORMAT_OBJS = ei_format_test@obj@ ei_format_test_decl@obj@ ei_runner@obj@
+EI_PRINT_OBJS = ei_print_test@obj@ ei_print_test_decl@obj@ ei_runner@obj@
+EI_CONNECT_OBJS = ei_connect_test@obj@ ei_connect_test_decl@obj@ ei_runner@obj@
+EI_ACCEPT_OBJS = ei_accept_test@obj@ ei_accept_test_decl@obj@ ei_runner@obj@
+MATCH_OBJS = match_test@obj@ match_test_decl@obj@ runner@obj@
+
+PROGS = eterm_test@exe@ format_test@exe@ print_term@exe@ match_test@exe@ ei_format_test@exe@ ei_print_test@exe@ ei_connect_test@exe@ ei_accept_test@exe@
+
+
+all: $(PROGS)
+
+eterm_test@exe@: $(ETERM_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o eterm_test $(ETERM_OBJS) $(LIBFLAGS)
+
+ext_test@exe@: $(EXT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o ext_test $(EXT_OBJS) $(LIBFLAGS)
+
+format_test@exe@: $(FORMAT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o format_test $(FORMAT_OBJS) $(LIBFLAGS)
+
+ei_format_test@exe@: $(EI_FORMAT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o ei_format_test $(EI_FORMAT_OBJS) $(LIBFLAGS)
+
+ei_print_test@exe@: $(EI_PRINT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o ei_print_test $(EI_PRINT_OBJS) $(LIBFLAGS)
+
+ei_connect_test@exe@: $(EI_CONNECT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o ei_connect_test $(EI_CONNECT_OBJS) $(LIBFLAGS)
+
+ei_accept_test@exe@: $(EI_ACCEPT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o ei_accept_test $(EI_ACCEPT_OBJS) $(LIBFLAGS)
+
+match_test@exe@: $(MATCH_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o match_test $(MATCH_OBJS) $(LIBFLGAS)
+
+print_term@exe@: print_term@obj@ $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o print_term print_term@obj@ $(LIBFLGAS)
diff --git a/lib/erl_interface/test/README b/lib/erl_interface/test/README
new file mode 100644
index 0000000000..e1af025ca3
--- /dev/null
+++ b/lib/erl_interface/test/README
@@ -0,0 +1,28 @@
+
+One way to create a new suite, copy an old one
+that is similar to a new one
+
+ % setenv SIMILAR ei_xyz
+ % setenv NEW ei_abc
+
+ % ct mkdir ${NEW}_SUITE_data
+ % ct mkelem ${NEW}_SUITE.erl
+ % cp ${SIMILAR}_SUITE.erl ${NEW}_SUITE.erl
+ % cp ${SIMILAR}_SUITE_data/* ${NEW}_SUITE_data/
+ % chmod ug+rw ${NEW}_SUITE_data/*
+ % mv ${NEW}_SUITE_data/${SIMILAR}_test.c ${NEW}_SUITE_data/${NEW}_test.c
+ % ct mkelem ${NEW}_SUITE_data/*
+
+Now edit "${NEW}_SUITE.erl" and the files in "${NEW}_SUITE_data/".
+
+To use a test suite you build it and put the result outside
+ClearCase. Then you create soft links to the ClearCase elements.
+
+ % setenv SRC /clearcase/otp/erts/lib/erl_interface/test
+ % setenv DST /ldisk/test
+ % cd $SRC
+ % clearmake -V release TESTROOT=$DST
+ % foreach f (`find . -type f`)
+ foreach> \rm -f /ldisk/test/erl_interface_test/$f
+ foreach> ln -s $SRC/$f $DST/erl_interface_test/$f
+ foreach> end
diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.first b/lib/erl_interface/test/all_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..b9ce689057
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/Makefile.first
@@ -0,0 +1,20 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+all:
+ erlc -W init_tc.erl
diff --git a/lib/erl_interface/test/all_SUITE_data/Makefile.src b/lib/erl_interface/test/all_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..9be2360656
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/Makefile.src
@@ -0,0 +1,45 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = .@DS@gccifier@exe@ -CC"$(CC0)"
+CFLAGS0 = @CFLAGS@ -I@erl_interface_include@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@
+EI_COMMON_OBJS = runner@obj@ ei_runner@obj@
+ALL_OBJS = gccifier@exe@ $(EI_COMMON_OBJS)
+
+CP=cp
+CHMOD=chmod
+
+all: $(ALL_OBJS)
+
+@IFEQ@ (@erl_interface_cross_compile@, true)
+gccifier@exe@:
+ $(CP) gccifier.sh gccifier@exe@
+ $(CHMOD) a+x gccifier@exe@
+@ELSE@
+gccifier@exe@: gccifier.c
+ $(CC0) $(CFLAGS0) -o gccifier@exe@ gccifier.c
+@ENDIF@
+
+clean:
+ $(RM) $(EI_COMMON_OBJS)
+ $(RM) init_tc.beam
+ $(RM) gccifier@exe@
diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.c b/lib/erl_interface/test/all_SUITE_data/ei_runner.c
new file mode 100644
index 0000000000..205f911e38
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.c
@@ -0,0 +1,400 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifndef __WIN32__
+#include <unistd.h>
+#endif
+#include <stdarg.h>
+
+#include "ei_runner.h"
+
+#ifndef __WIN32__
+#define _O_BINARY 0
+#define _setmode(fd, mode)
+#endif
+
+#define HEADER_SIZE 4
+
+static char* progname; /* Name of this program (from argv[0]). */
+static int fd_from_erl; /* File descriptor from Erlang. */
+static int fd_to_erl; /* File descriptor to Erlang. */
+
+static int packet_loop();
+static void ensure_buf_big_enough();
+static int readn();
+static void reply(char* buf, unsigned size);
+static void dump();
+
+void
+run_tests(char* argv0, TestCase test_cases[], unsigned number)
+{
+ int i;
+ int n;
+ char* packet;
+
+ progname = argv0;
+ _setmode(0, _O_BINARY);
+ _setmode(1, _O_BINARY);
+ fd_from_erl = 0;
+ fd_to_erl = 1;
+
+ packet = read_packet(&n);
+
+ /*
+ * Dispatch to the appropriate test function.
+ */
+
+ i = packet[0] * 256 + packet[1];
+ if (i >= number) {
+ fprintf(stderr, "%s: bad test case number %d",
+ progname, i);
+ free(packet);
+ exit(1);
+ } else {
+ (*test_cases[i])();
+ free(packet);
+ }
+}
+
+
+/***********************************************************************
+ *
+ * R e a d i n g p a c k e t s
+ *
+ ************************************************************************/
+
+/*
+ * Reads an Erlang term.
+ *
+ * Only accepts 't' (term) or 'e' (end of test),
+ * exits program on error
+ * returns 1 on 'e', 0 on 't'
+ */
+int get_bin_term(ei_x_buff* x, ei_term* term)
+{
+ int len, version;
+
+ ei_x_free(x);
+ x->buff = read_packet(&len);
+ x->buffsz = len;
+ x->index = 0;
+ switch (x->buff[x->index++]) {
+ case 'e':
+ return 1;
+ case 't':
+ if (ei_decode_version(x->buff, &x->index, &version) < 0
+ || ei_decode_ei_term(x->buff, &x->index, term) < 0) {
+ fail("Failed to decode term");
+ exit(0);
+ }
+ return 0;
+ default:
+ fprintf(stderr, "Garbage received: ");
+ dump(x->buff, len, 16);
+ putc('\n', stderr);
+ fail("C program received garbage");
+ exit(1);
+ }
+}
+
+
+/*
+ * Reads a packet from Erlang. The packet must be a standard {packet, 2}
+ * packet. This function aborts if any error is detected (including EOF).
+ *
+ * Returns: The number of bytes in the packet.
+ */
+
+char *read_packet(int *len)
+{
+
+ unsigned char* io_buf = NULL; /* Buffer for file i/o. */
+ int i;
+ unsigned char header[HEADER_SIZE];
+ unsigned packet_length; /* Length of current packet. */
+ int bytes_read;
+
+ /*
+ * Read the packet header.
+ */
+
+ bytes_read = readn(fd_from_erl, header, HEADER_SIZE);
+
+ if (bytes_read == 0) {
+ fprintf(stderr, "%s: Unexpected end of file\n", progname);
+ exit(1);
+ }
+ if (bytes_read != HEADER_SIZE) {
+ fprintf(stderr, "%s: Failed to read packet header\n", progname);
+ exit(1);
+ }
+
+ /*
+ * Get the length of this packet.
+ */
+
+ packet_length = 0;
+
+ for (i = 0; i < HEADER_SIZE; i++)
+ packet_length = (packet_length << 8) | header[i];
+
+ if (len) *len=packet_length; /* report length only if caller requested it */
+
+ if ((io_buf = (char *) malloc(packet_length)) == NULL) {
+ fprintf(stderr, "%s: insufficient memory for i/o buffer of size %d\n",
+ progname, packet_length);
+ exit(1);
+ }
+
+ /*
+ * Read the packet itself.
+ */
+
+ bytes_read = readn(fd_from_erl, io_buf, packet_length);
+ if (bytes_read != packet_length) {
+ fprintf(stderr, "%s: couldn't read packet of length %d\r\n",
+ progname, packet_length);
+ free(io_buf);
+ exit(1);
+ }
+
+ return io_buf;
+}
+
+
+/***********************************************************************
+ * S e n d i n g r e p l i e s
+ *
+ * The functions below send various types of replies back to Erlang.
+ * Each reply start with a letter indicating the type of reply.
+ *
+ * Reply Translated to on Erlang side
+ * ----- ----------------------------
+ * [$b|Bytes] {bytes, Bytes}
+ * [$e] eot
+ * [$f] test_server:fail()
+ * [$f|Reason] test_server:fail(Reason)
+ * [$t|EncodedTerm] {term, Term}
+ * [$N] 'NULL'
+ * [$m|Message] io:format("~s", [Message]) (otherwise ignored)
+ *
+ ***********************************************************************/
+
+/*
+ * This function reports the outcome of a test fail. It is useful if
+ * you implement a test case entirely in C code.
+ *
+ * If the ok argument is zero, a [$f] reply will be sent to the
+ * Erlang side (causing test_server:fail() to be called); otherwise,
+ * the atom 'eot' will be sent to Erlang.
+ *
+ * If you need to provide more details on a failure, use the fail() function.
+ */
+
+void
+do_report(file, line, ok)
+ char* file;
+ int line;
+ int ok; /* Zero if failed; non-zero otherwise. */
+{
+ char reason;
+ /*unsigned long ab;
+ unsigned long fb;*/
+
+ reason = ok ? 'e' : 'f';
+
+ if (!ok) {
+ do_fail(file, line, "Generic failure");
+ } else {
+ /* release all unallocated blocks */
+ /*erl_eterm_release();*/
+ /* check mem usage stats */
+ /*erl_eterm_statistics(&ab, &fb);*/
+ /*if ((ab == 0) && (fb == 0) ) {*/
+ reply(&reason, 1);
+ /*}
+ else {
+ char sbuf[128];
+
+ sprintf(sbuf, "still %lu terms allocated,"
+ " %lu on freelist at end of test", ab, fb);
+ do_fail(file, line, sbuf);
+ }*/
+ }
+}
+
+
+/*
+ * This function causes a call to test_server:fail(Reason) on the
+ * Erlang side.
+ */
+
+void do_fail(char* file, int line, char* reason)
+{
+ char sbuf[2048];
+
+ sbuf[0] = 'f';
+ sprintf(sbuf+1, "%s, line %d: %s", file, line, reason);
+ reply(sbuf, 1+strlen(sbuf+1));
+}
+
+/*
+ * This function sends a message to the Erlang side.
+ * The message will be written to the test servers log file,
+ * but will otherwise be completly ignored.
+ */
+
+void message(char* format, ...)
+{
+ va_list ap;
+ char sbuf[1024];
+
+ sbuf[0] = 'm';
+ va_start(ap, format);
+ vsprintf(sbuf+1, format, ap);
+ va_end(ap);
+
+ reply(sbuf, 1+strlen(sbuf+1));
+}
+
+/*
+ * This function sends the given binary term to the Erlang side,
+ * where it will be received as {term, Term} (prefix 't').
+ */
+void send_bin_term(ei_x_buff* x)
+{
+ ei_x_buff x2;
+ ei_x_new(&x2);
+ x2.buff[x2.index++] = 't';
+ ei_x_append(&x2, x);
+ reply(x2.buff, x2.index);
+ ei_x_free(&x2);
+}
+
+/*
+ * This function sends a raw buffer of data to the
+ * Erlang side, where it will be received as {bytes, Bytes} (prefix 'b').
+ */
+void send_buffer(char* buf, int size)
+{
+ char* send_buf;
+
+ send_buf = (char *) malloc(size+1);
+ send_buf[0] = 'b';
+ memcpy(send_buf+1, buf, size);
+ reply(send_buf, size+1);
+ free(send_buf);
+}
+
+/***********************************************************************
+ *
+ * P r i v a t e h e l p e r s
+ *
+ ***********************************************************************/
+
+/*
+ * Sends a packet back to Erlang.
+ */
+static void reply(char* reply_buf, unsigned size)
+{
+ int n; /* Temporary to hold size. */
+ int i; /* Loop counter. */
+ char* buf;
+
+
+ buf = (char *) malloc(size+HEADER_SIZE);
+ memcpy(buf+HEADER_SIZE, reply_buf, size);
+
+ /*
+ * Fill the header starting with the least significant byte.
+ */
+ n = size;
+ for (i = HEADER_SIZE-1; i >= 0; i--) {
+ buf[i] = (char) n; /* Store least significant byte. */
+ n = n >> 8;
+ }
+
+ size += HEADER_SIZE;
+ write(fd_to_erl, buf, size);
+ free(buf);
+}
+
+
+/*
+ * Reads len number of bytes.
+ */
+
+static int
+readn(fd, buf, len)
+ int fd; /* File descriptor to read from. */
+ unsigned char *buf; /* Store in this buffer. */
+ int len; /* Number of bytes to read. */
+{
+ int n; /* Byte count in last read call. */
+ int sofar = 0; /* Bytes read so far. */
+
+ do {
+ if ((n = read(fd, buf+sofar, len-sofar)) <= 0)
+ /* error or EOF in read */
+ return(n);
+ sofar += n;
+ } while (sofar < len);
+ return sofar;
+}
+
+void
+dump(buf, sz, max)
+ unsigned char* buf;
+ int sz;
+ int max;
+{
+ int i, imax;
+ char comma[5] = ",";
+
+ if (!sz)
+ return;
+ if (sz > max)
+ imax = max;
+ else
+ imax = sz;
+
+ for (i=0; i<imax; i++) {
+ if (i == imax-1) {
+ if (sz > max)
+ strcpy(comma, ",...");
+ else
+ comma[0] = 0;
+ }
+ if (isdigit(buf[i]))
+ fprintf(stderr, "%u%s", (int)(buf[i]), comma);
+ else {
+ if (isalpha(buf[i])) {
+ fprintf(stderr, "%c%s", buf[i], comma);
+ }
+ else
+ fprintf(stderr, "%u%s", (int)(buf[i]), comma);
+ }
+ }
+}
+
diff --git a/lib/erl_interface/test/all_SUITE_data/ei_runner.h b/lib/erl_interface/test/all_SUITE_data/ei_runner.h
new file mode 100644
index 0000000000..96d6a1cbf7
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/ei_runner.h
@@ -0,0 +1,61 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include "ei.h"
+
+typedef void (*TestCase)(void);
+
+#define TESTCASE(name) void name(void)
+#define ASIZE(a) (sizeof(a)/sizeof(a[0]))
+
+void run_tests(char* argv0, TestCase cases[], unsigned number);
+
+#ifndef _MSC_VER
+# define ll(val) (val##LL)
+#else /* assume gcc or C99 */
+# define ll(val) (val##i64)
+#endif
+
+#ifndef _MSC_VER
+# define ull(val) (val##LL)
+#else /* assume gcc or C99 */
+# define ull(val) (val##i64)
+#endif
+
+/*
+ * Reading.
+ */
+
+int get_bin_term(ei_x_buff* x, ei_term* term);
+char *read_packet(int *len);
+
+/*
+ * Sending replies.
+ */
+
+#define fail(reason) do_fail(__FILE__, __LINE__, reason)
+#define report(ok) do_report(__FILE__, __LINE__, ok)
+
+void do_report(char* file, int line, int ok);
+void do_fail(char* file, int line, char* reason);
+void send_buffer(char* buf, int size);
+void message(char* format, ...);
+
+void send_bin_term(ei_x_buff* x);
+
diff --git a/lib/erl_interface/test/all_SUITE_data/gccifier.c b/lib/erl_interface/test/all_SUITE_data/gccifier.c
new file mode 100644
index 0000000000..9f556fc4ed
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/gccifier.c
@@ -0,0 +1,317 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2005-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ *
+
+ */
+
+/*
+ * A compiler wrapper that translate (some) gcc command line arguments
+ * to the Visual C++ compiler and (of course) the gcc compiler. It also
+ * makes some changes in the command line arguments when debug compiling.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+
+#if !defined(__WIN32__)
+#define USE_EXEC
+#include <unistd.h>
+#endif
+
+
+#ifdef __WIN32__
+#define EOL "\r\n"
+#else
+#define EOL "\n"
+#endif
+
+#define ARGS_INCR 20
+
+static char *prog;
+
+typedef struct {
+ char **vec;
+ int no;
+ int ix;
+ int chars;
+} args_t;
+
+static void
+enomem(void)
+{
+ fprintf(stderr, "%s: Out of memory%s", prog, EOL);
+ exit(1);
+}
+
+static void
+save_arg(args_t *args, char *arg1, ...)
+{
+ char *carg;
+ va_list argp;
+
+ va_start(argp, arg1);
+ carg = arg1;
+ while (carg) {
+ if (args->no <= args->ix) {
+ args->vec = (char **) (args->no
+ ? realloc((void *) args->vec,
+ (sizeof(char *)
+ *(args->no + ARGS_INCR + 1)))
+ : malloc((sizeof(char *)
+ *(args->no + ARGS_INCR + 1))));
+ if (!args->vec)
+ enomem();
+ args->no += ARGS_INCR;
+ }
+ args->vec[args->ix++] = carg;
+ args->chars += strlen(carg);
+ carg = va_arg(argp, char *);
+ }
+ args->vec[args->ix++] = " ";
+ args->chars++;
+ va_end(argp);
+}
+
+static int
+is_prefix(char *prfx, char **str)
+{
+ int i;
+ for (i = 0; prfx[i] && (*str)[i]; i++) {
+ if (prfx[i] != (*str)[i])
+ return 0;
+ }
+ if (!prfx[i]) {
+ *str = &(*str)[i];
+ return 1;
+ }
+ return 0;
+}
+
+static void
+cpy(char **dst, char *src)
+{
+ int i;
+ for (i = 0; src[i]; i++)
+ (*dst)[i] = src[i];
+ *dst = &(*dst)[i];
+}
+
+typedef enum {
+ STDLIB_NONE,
+ STDLIB_MD,
+ STDLIB_ML,
+ STDLIB_MT
+} stdlib_t;
+
+int
+main(int argc, char *argv[])
+{
+ int res;
+ int i;
+ size_t cmd_len;
+ char *cmd;
+ char *cmd_end;
+ char *cc = NULL;
+ args_t args = {0};
+ int is_debug = 0;
+ int is_purify = 0;
+ int is_quantify = 0;
+ int is_purecov = 0;
+#ifdef __WIN32__
+ int is_shared = 0;
+ stdlib_t stdlib = STDLIB_NONE;
+ char *shared_flag = "";
+ char *stdlib_flag = "";
+ int have_link_args = 0;
+ args_t link_args = {0};
+
+#define CHECK_FIRST_LINK_ARG \
+ if (!have_link_args) { \
+ save_arg(&link_args, "-link", NULL); \
+ have_link_args = 1; \
+ }
+#else /* #ifdef __WIN32__ */
+#define CHECK_FIRST_LINK_ARG
+#endif /* #ifdef __WIN32__ */
+
+ prog = argv[0];
+
+
+ for (i = 1; i < argc; i++) {
+ char *arg = argv[i];
+ if (is_prefix("-CC", &arg)) {
+ cc = arg;
+ }
+ else if (is_prefix("-O", &arg)) {
+ if (!is_debug)
+ save_arg(&args, argv[i], NULL);
+ }
+ else if (strcmp("-DDEBUG", arg) == 0) {
+ save_arg(&args, arg, NULL);
+#ifdef __WIN32__
+ set_debug:
+#endif
+ if (!is_debug) {
+ int j;
+ is_debug = 1;
+#ifdef __WIN32__
+ save_arg(&args, "-Z7", NULL);
+ CHECK_FIRST_LINK_ARG;
+ save_arg(&link_args, "-debug", NULL);
+ save_arg(&link_args, "-pdb:none", NULL);
+#endif
+ for (j = 0; j < args.ix; j++) {
+ char *tmp_arg = args.vec[j];
+ if (is_prefix("-O", &tmp_arg))
+ args.vec[j] = "";
+ }
+ }
+ }
+ else if (strcmp("-DPURIFY", arg) == 0) {
+ save_arg(&args, arg, NULL);
+ is_purify = 1;
+ }
+ else if (strcmp("-DQUANTIFY", arg) == 0) {
+ save_arg(&args, arg, NULL);
+ is_quantify = 1;
+ }
+ else if (strcmp("-DPURECOV", arg) == 0) {
+ save_arg(&args, arg, NULL);
+ is_purecov = 1;
+ }
+#ifdef __WIN32__
+ else if (strcmp("-g", arg) == 0) {
+ goto set_debug;
+ }
+ else if (strcmp("-MD", arg) == 0)
+ stdlib = STDLIB_MD;
+ else if (strcmp("-MDd", arg) == 0) {
+ stdlib = STDLIB_MD;
+ goto set_debug;
+ }
+ else if (strcmp("-ML", arg) == 0)
+ stdlib = STDLIB_ML;
+ else if (strcmp("-MLd", arg) == 0) {
+ stdlib = STDLIB_ML;
+ goto set_debug;
+ }
+ else if (strcmp("-MT", arg) == 0)
+ stdlib = STDLIB_MT;
+ else if (strcmp("-MTd", arg) == 0) {
+ stdlib = STDLIB_MT;
+ goto set_debug;
+ }
+ else if (strcmp("-shared", arg) == 0 || strcmp("-LD", arg) == 0)
+ is_shared = 1;
+ else if (strcmp("-LDd", arg) == 0) {
+ is_shared = 1;
+ goto set_debug;
+ }
+ else if (strcmp("-Wall", arg) == 0) {
+ save_arg(&args, "-W3", NULL);
+ }
+ else if (is_prefix("-L", &arg)) {
+ CHECK_FIRST_LINK_ARG;
+ save_arg(&link_args, "-libpath:", arg, NULL);
+ }
+#endif /* #ifdef __WIN32__ */
+ else if (is_prefix("-l", &arg)) {
+ CHECK_FIRST_LINK_ARG;
+ if (is_debug && strcmp("ethread", arg) == 0)
+ arg = "ethread.debug";
+ else if (is_purify && strcmp("ethread", arg) == 0)
+ arg = "ethread.purify";
+ else if (is_quantify && strcmp("ethread", arg) == 0)
+ arg = "ethread.quantify";
+ else if (is_purecov && strcmp("ethread", arg) == 0)
+ arg = "ethread.purecov";
+#ifdef __WIN32__
+ else if (strcmp("socket", arg) == 0)
+ arg = "ws2_32";
+ save_arg(&link_args, arg, ".lib", NULL);
+#else
+ save_arg(&args, "-l", arg, NULL);
+#endif
+ }
+ else
+ save_arg(&args, argv[i], NULL);
+ }
+
+ if (!cc || !cc[0]) {
+ fprintf(stderr, "%s: Missing compulsory -CC flag%s", prog, EOL);
+ exit(1);
+ }
+
+ cmd_len = strlen(cc) + 1 + args.chars + 1;
+
+#ifdef __WIN32__
+ if (is_shared)
+ shared_flag = is_debug ? "-LDd " : "-LD ";
+ switch (stdlib) {
+ case STDLIB_MD: stdlib_flag = is_debug ? "-MDd " : "-MD "; break;
+ case STDLIB_ML: stdlib_flag = is_debug ? "-MLd " : "-ML "; break;
+ case STDLIB_MT: stdlib_flag = is_debug ? "-MTd " : "-MT "; break;
+ case STDLIB_NONE: break;
+ }
+
+ cmd_len += strlen(shared_flag) + strlen(stdlib_flag) + link_args.chars;
+#endif
+
+ cmd = (char *) malloc(sizeof(char) * cmd_len);
+
+ if (!cmd)
+ enomem();
+ cmd_end = cmd;
+ cpy(&cmd_end, cc);
+ cpy(&cmd_end, " ");
+#ifdef __WIN32__
+ cpy(&cmd_end, stdlib_flag);
+ cpy(&cmd_end, shared_flag);
+#endif
+ for (i = 0; i < args.ix; i++)
+ cpy(&cmd_end, args.vec[i]);
+#ifdef __WIN32__
+ for (i = 0; i < link_args.ix; i++)
+ cpy(&cmd_end, link_args.vec[i]);
+#endif
+ *cmd_end = '\0';
+
+ printf("==> %s%s", cmd, EOL);
+ fflush(stdout);
+
+#ifdef USE_EXEC
+ (void) execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
+ perror(NULL);
+ res = 1;
+#else
+ res = system(cmd);
+#endif
+
+ free((void *) args.vec);
+#ifdef __WIN32__
+ free((void *) link_args.vec);
+#endif
+ free((void *) cmd);
+
+ if (res < 0)
+ res = 1;
+ return res;
+}
diff --git a/lib/erl_interface/test/all_SUITE_data/gccifier.sh b/lib/erl_interface/test/all_SUITE_data/gccifier.sh
new file mode 100755
index 0000000000..42253213b1
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/gccifier.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2005-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+CC=`echo "$1" | sed -e "s/-CC//"`
+shift
+echo "->"
+echo "$CC $*"
+$CC $*
+echo ""
diff --git a/lib/erl_interface/test/all_SUITE_data/init_tc.erl b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
new file mode 100644
index 0000000000..8157d590fc
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/init_tc.erl
@@ -0,0 +1,101 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(init_tc).
+
+-export([run/1]).
+
+%% The argument should be a list of filenames (atoms), without extension
+%% A .c extension is assumed.
+%%
+
+run([Name|Rest]) ->
+ case catch run1(atom_to_list(Name)) of
+ {'EXIT', Reason} ->
+ io:format("Failed: ~p~n", [Reason]),
+ halt(1);
+ _Other ->
+ run(Rest)
+ end;
+run([]) ->
+ ok.
+
+run1(Name) ->
+ CFile = Name ++ ".c",
+ {ok, Bin} = file:read_file(CFile),
+ String = binary_to_list(Bin),
+
+ %% This ConstPart stuff is because you can't retrieve part of a match.
+ %% Long live Perl!
+
+ ConstPart = "\nTESTCASE\\(",
+ ConstPartLen = 10,
+ {match, Matches} = regexp:matches(String, ConstPart++"[_a-zA-Z]*"),
+ Cases = get_names(Matches, ConstPartLen, Bin, []),
+ generate(Name, Cases).
+
+get_names([{Start, Length}|Rest], Skip, Bin, Result) ->
+ Name = binary_to_list(Bin, Start+Skip, Start+Length-1),
+ get_names(Rest, Skip, Bin, [Name|Result]);
+get_names([], _Skip, _Bin, Result) ->
+ lists:reverse(Result).
+
+generate(TcName, Cases) ->
+ Hrl = TcName ++ "_cases.hrl",
+ {ok, HrlFile} = file:open(Hrl, write),
+ {ok, Dir} = file:get_cwd(),
+ generate_hrl(Cases, HrlFile, {filename:join(Dir, TcName), 0}),
+ file:close(HrlFile),
+ C = TcName ++ "_decl.c",
+ {ok, CFile} = file:open(C, write),
+ generate_c(Cases, CFile, TcName),
+ file:close(CFile).
+
+generate_hrl([Case|Rest], File, {Name, Number}) ->
+ io:format(File, "-define(~s, {\"~s\", ~w}).~n", [Case, Name, Number]),
+ generate_hrl(Rest, File, {Name, Number+1});
+generate_hrl([], _, _) ->
+ ok.
+
+generate_c(Cases, File, TcName) ->
+ E= case lists:prefix("ei_", TcName) of
+ true -> "ei_";
+ false -> ""
+ end,
+ io:format(File, "#include \"~srunner.h\"\n", [E]),
+ lists:foreach(
+ fun(Case) ->
+ io:format(File, "extern void ~s(void);~n",
+ [Case]) end,
+ Cases),
+ io:format(File, "~nstatic TestCase test_cases[] = {~n", []),
+ lists:foreach(fun(Case) -> io:format(File, " ~s,~n", [Case]) end, Cases),
+ io:format(File, "~s",
+ [["};\n\n",
+ "#ifdef VXWORKS\n",
+ "int ", TcName, "(int argc, char* argv[])\n",
+ "#else\n",
+ "int main(int argc, char* argv[])\n",
+ "#endif\n",
+ "{\n",
+ " run_tests(argv[0], test_cases, ",
+ "sizeof(test_cases)/sizeof(test_cases[0]));\n",
+ " return 0;\n",
+ "}\n"]]).
diff --git a/lib/erl_interface/test/all_SUITE_data/reclaim.h b/lib/erl_interface/test/all_SUITE_data/reclaim.h
new file mode 100644
index 0000000000..00fdfc38dc
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/reclaim.h
@@ -0,0 +1,151 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ *
+
+ */
+#ifndef _RECLAIM_H
+#define _RECLAIM_H
+
+
+/* The Erlang release for VxWorks includes a simple mechanism for
+ "resource reclamation" at task exit - it allows replacement of the
+ functions that open/close "files" and malloc/free memory with versions
+ that keep track, to be able to "reclaim" file descriptors and memory
+ when a task exits (regardless of *how* it exits).
+
+ The interface to this mechanism is made available via this file,
+ with the following caveats:
+
+ - The interface may change (or perhaps even be removed, though that
+ isn't likely until VxWorks itself provides similar functionality)
+ in future releases - i.e. you must always use the version of this
+ file that comes with the Erlang release you are using.
+
+ - Disaster is guaranteed if you use the mechanism incorrectly (see
+ below for the correct way), e.g. allocate memory with the "tracking"
+ version of malloc() and free it with the "standard" version of free().
+
+ - The mechanism (of course) incurs some performance penalty - thus
+ for a simple program you may be better off with careful programming,
+ making sure that you do whatever close()/free()/etc calls that are
+ appropriate at all exit points (though if you need to guard against
+ taskDelete() etc, things get messy...).
+
+ To use the mechanism, simply program your application normally, i.e.
+ use open()/close()/malloc()/free() etc as usual, but #include this
+ file before any usage of the relevant functions. NOTE: To avoid the
+ "disaster" mentioned above, you *must* #include it in *all* (or none)
+ of the files that manipulate a particular file descriptor, allocated
+ memory area, etc.
+
+ Before any task that uses this utility is loaded (which includes the
+ erlang emulator), the reclaim.o object file has to be loaded and
+ the function reclaim_init() has to be called. reclaim_init should be called
+ only _ONCE_ in a systems lifetime and has only a primitive guard
+ against multiple calls (i.e. a global variable is checked). Therefore
+ the initialization should occur either in the start script of the system
+ or (even better) in the usrInit() part of system initialization. The
+ object file itself should be loaded only once, so linking it with the
+ kernel is a good idea, linking with each application is an extremely bad
+ dito. Make really sure that it's loaded _before_ any application that
+ uses it if You want to load it in the startup script.
+
+ If You dont want to have #define's for the posix/stdio names
+ of the file/memory operations (i.e. no #define malloc save_malloc etc),
+ #define RECLAIM_NO_ALIAS in Your source before reclaim.h is included.
+*/
+
+#include <vxWorks.h> /* STATUS, size_t */
+#include <sockLib.h> /* struct sockaddr */
+#include <stdio.h> /* FILE */
+
+#if defined(__STDC__)
+#define _RECLAIM_DECL_FUN(RetType, FunName, ParamList) \
+extern RetType FunName##ParamList
+#define _RECLAIM_VOID_PTR void *
+#define _RECLAIM_VOID_PARAM void
+#define _RECLAIM_VOID_RETURN void
+#elif defined(__cplusplus)
+#define _RECLAIM_DECL_FUN(RetType, FunName, ParamList) \
+extern "C" RetType FunName##ParamList
+#define _RECLAIM_VOID_PTR void *
+#define _RECLAIM_VOID_PARAM
+#define _RECLAIM_VOID_RETURN void
+#else
+#define _RECLAIM_DECL_FUN(RetType, FunName, Ignore) extern RetType FunName()
+#define DECLARE_FUNCTION_TYPE(RetType, Type, PList) typedef RetType (* Type)()
+#define _RECLAIM_VOID_PTR char *
+#define _RECLAIM_VOID_PARAM
+#define _RECLAIM_VOID_RETURN
+#endif /* __STDC__ / __cplusplus */
+
+/* Initialize the facility, on a per system basis. */
+_RECLAIM_DECL_FUN(STATUS, reclaim_init, (_RECLAIM_VOID_PARAM));
+
+/* File descriptor operations */
+_RECLAIM_DECL_FUN(int,save_open,(char *, int, ...));
+_RECLAIM_DECL_FUN(int,save_creat,(char *, int));
+_RECLAIM_DECL_FUN(int,save_socket,(int, int, int));
+_RECLAIM_DECL_FUN(int,save_accept,(int, struct sockaddr *, int *));
+_RECLAIM_DECL_FUN(int,save_close,(int));
+/* Interface to add an fd to what's reclaimed even though it's not open with
+ one of the above functions */
+_RECLAIM_DECL_FUN(_RECLAIM_VOID_RETURN, save_fd, (int fd));
+#ifndef RECLAIM_NO_ALIAS
+#define open save_open
+#define creat save_creat
+#define socket save_socket
+#define accept save_accept
+#define close save_close
+#endif
+/* Stdio file operations */
+_RECLAIM_DECL_FUN(FILE *, save_fopen, (char *, char *));
+_RECLAIM_DECL_FUN(FILE *, save_fdopen, (int, char *));
+_RECLAIM_DECL_FUN(FILE *, save_freopen, (char *, char *, FILE *));
+_RECLAIM_DECL_FUN(int, save_fclose, (FILE *));
+/* XXX Should do opendir/closedir too... */
+#ifndef RECLAIM_NO_ALIAS
+#define fopen save_fopen
+#define fdopen save_fdopen
+#define freopen save_freopen
+#define fclose save_fclose
+#endif
+/* Memory allocation */
+_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, save_malloc, (size_t));
+_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, save_calloc, (size_t, size_t));
+_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, save_realloc,
+ (_RECLAIM_VOID_PTR, size_t));
+_RECLAIM_DECL_FUN(void, save_free, (_RECLAIM_VOID_PTR));
+_RECLAIM_DECL_FUN(void, save_cfree, (_RECLAIM_VOID_PTR));
+#ifndef RECLAIM_NO_ALIAS
+#define malloc save_malloc
+#define calloc save_calloc
+#define realloc save_realloc
+#define free save_free
+#define cfree save_cfree
+#endif
+/* Generic interfaces to malloc etc... */
+_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, plain_malloc, (size_t));
+_RECLAIM_DECL_FUN(_RECLAIM_VOID_PTR, plain_realloc,
+ (_RECLAIM_VOID_PTR, size_t));
+_RECLAIM_DECL_FUN(void, plain_free, (_RECLAIM_VOID_PTR));
+#endif /* _RECLAIM_H */
+
+
+
+
diff --git a/lib/erl_interface/test/all_SUITE_data/runner.c b/lib/erl_interface/test/all_SUITE_data/runner.c
new file mode 100644
index 0000000000..24df0f5f40
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/runner.c
@@ -0,0 +1,457 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifndef __WIN32__
+#include <unistd.h>
+#endif
+#include <stdarg.h>
+
+#include "runner.h"
+
+#ifndef __WIN32__
+#define _O_BINARY 0
+#define _setmode(fd, mode)
+#endif
+
+#define HEADER_SIZE 4
+
+static char* progname; /* Name of this program (from argv[0]). */
+static int fd_from_erl; /* File descriptor from Erlang. */
+static int fd_to_erl; /* File descriptor to Erlang. */
+
+static int packet_loop();
+static void ensure_buf_big_enough();
+static int readn();
+static void reply(char* buf, unsigned size);
+static void dump();
+
+void
+run_tests(char* argv0, TestCase test_cases[], unsigned number)
+{
+ int i;
+ int n;
+ char* packet;
+
+ progname = argv0;
+ _setmode(0, _O_BINARY);
+ _setmode(1, _O_BINARY);
+ fd_from_erl = 0;
+ fd_to_erl = 1;
+
+ packet = read_packet(&n);
+
+ /*
+ * Dispatch to the appropriate test function.
+ */
+
+ i = packet[0] * 256 + packet[1];
+ if (i >= number) {
+ fprintf(stderr, "%s: bad test case number %d",
+ progname, i);
+ free(packet);
+ exit(1);
+ } else {
+ (*test_cases[i])();
+ free(packet);
+ }
+}
+
+
+/***********************************************************************
+ *
+ * R e a d i n g p a c k e t s
+ *
+ ************************************************************************/
+
+/*
+ * Reads an Erlang term.
+ *
+ * Returns: A pointer to a term (an ETERM structure) if there was
+ * at term available, or a NULL pointer if there was an 'eot' (end-of-test)
+ * packet. Aborts if anything else received.
+ */
+
+ETERM*
+get_term(void)
+{
+ char* encoded;
+ ETERM* term;
+ int n;
+
+ encoded = read_packet(&n);
+
+ switch (encoded[0]) {
+ case 'e':
+ free(encoded);
+ return NULL;
+ case 't':
+ term = erl_decode(encoded+1);
+ free(encoded);
+ if (term == NULL) {
+ fail("Failed to decode term");
+ exit(0);
+ }
+ return term;
+ default:
+ fprintf(stderr, "Garbage received: ");
+ dump(encoded, n, 16);
+ putc('\n', stderr);
+ fail("C program received garbage");
+ free(encoded);
+ exit(1);
+ }
+}
+
+
+/*
+ * Reads a packet from Erlang. The packet must be a standard {packet, 2}
+ * packet. This function aborts if any error is detected (including EOF).
+ *
+ * Returns: The number of bytes in the packet.
+ */
+
+char *read_packet(int *len)
+{
+
+ unsigned char* io_buf = NULL; /* Buffer for file i/o. */
+ int i;
+ unsigned char header[HEADER_SIZE];
+ unsigned packet_length; /* Length of current packet. */
+ int bytes_read;
+
+ /*
+ * Read the packet header.
+ */
+
+ bytes_read = readn(fd_from_erl, header, HEADER_SIZE);
+
+ if (bytes_read == 0) {
+ fprintf(stderr, "%s: Unexpected end of file\n", progname);
+ exit(1);
+ }
+ if (bytes_read != HEADER_SIZE) {
+ fprintf(stderr, "%s: Failed to read packet header\n", progname);
+ exit(1);
+ }
+
+ /*
+ * Get the length of this packet.
+ */
+
+ packet_length = 0;
+
+ for (i = 0; i < HEADER_SIZE; i++)
+ packet_length = (packet_length << 8) | header[i];
+
+ if (len) *len=packet_length; /* report length only if caller requested it */
+
+ if ((io_buf = (char *) malloc(packet_length)) == NULL) {
+ fprintf(stderr, "%s: insufficient memory for i/o buffer of size %d\n",
+ progname, packet_length);
+ exit(1);
+ }
+
+ /*
+ * Read the packet itself.
+ */
+
+ bytes_read = readn(fd_from_erl, io_buf, packet_length);
+ if (bytes_read != packet_length) {
+ fprintf(stderr, "%s: couldn't read packet of length %d\r\n",
+ progname, packet_length);
+ free(io_buf);
+ exit(1);
+ }
+
+ return io_buf;
+}
+
+
+/***********************************************************************
+ * S e n d i n g r e p l i e s
+ *
+ * The functions below send various types of replies back to Erlang.
+ * Each reply start with a letter indicating the type of reply.
+ *
+ * Reply Translated to on Erlang side
+ * ----- ----------------------------
+ * [$b|Bytes] {bytes, Bytes}
+ * [$e] eot
+ * [$f] test_server:fail()
+ * [$f|Reason] test_server:fail(Reason)
+ * [$t|EncodedTerm] {term, Term}
+ * [$N] 'NULL'
+ * [$m|Message] io:format("~s", [Message]) (otherwise ignored)
+ *
+ ***********************************************************************/
+
+/*
+ * This function reports the outcome of a test fail. It is useful if
+ * you implement a test case entirely in C code.
+ *
+ * If the ok argument is zero, a [$f] reply will be sent to the
+ * Erlang side (causing test_server:fail() to be called); otherwise,
+ * the atom 'eot' will be sent to Erlang.
+ *
+ * If you need to provide more details on a failure, use the fail() function.
+ */
+
+void
+do_report(file, line, ok)
+ char* file;
+ int line;
+ int ok; /* Zero if failed; non-zero otherwise. */
+{
+ char reason;
+ unsigned long ab;
+ unsigned long fb;
+
+ reason = ok ? 'e' : 'f';
+
+ if (!ok) {
+ do_fail(file, line, "Generic failure");
+ } else {
+ /* release all unallocated blocks */
+ erl_eterm_release();
+ /* check mem usage stats */
+ erl_eterm_statistics(&ab, &fb);
+ if ((ab == 0) && (fb == 0) ) {
+ reply(&reason, 1);
+ }
+ else {
+ char sbuf[128];
+
+ sprintf(sbuf, "still %lu terms allocated,"
+ " %lu on freelist at end of test", ab, fb);
+ do_fail(file, line, sbuf);
+ }
+ }
+}
+
+
+/*
+ * This function causes a call to test_server:fail(Reason) on the
+ * Erlang side.
+ */
+
+void
+do_fail(char* file, int line, char* reason)
+{
+ char sbuf[2048];
+
+ sbuf[0] = 'f';
+ sprintf(sbuf+1, "%s, line %d: %s", file, line, reason);
+ reply(sbuf, 1+strlen(sbuf+1));
+}
+
+/*
+ * This function sends a message to the Erlang side.
+ * The message will be written to the test servers log file,
+ * but will otherwise be completly ignored.
+ */
+
+void
+message(char* format, ...)
+{
+ va_list ap;
+ char sbuf[1024];
+
+ sbuf[0] = 'm';
+ va_start(ap, format);
+ vsprintf(sbuf+1, format, ap);
+ va_end(ap);
+
+ reply(sbuf, 1+strlen(sbuf+1));
+}
+
+/*
+ * This function sends the given term to the Erlang side,
+ * where it will be received as {term, Term}.
+ *
+ * If the given pointer is NULL (indicating an invalid term),
+ * the result on the Erlang side will be the atom 'NULL'.
+ *
+ * After sending the term, this function frees the term by
+ * calling erl_free_term().
+ */
+
+void
+send_term(term)
+ ETERM* term; /* Term to be sent to Erlang side. */
+{
+ char encoded[64*1024];
+ int n;
+
+ if (term == NULL) {
+ encoded[0] = 'N';
+ n = 1;
+ } else {
+ encoded[0] = 't';
+ n = 1 + erl_encode(term, encoded+1);
+ erl_free_term(term);
+ }
+ reply(encoded, n);
+}
+
+#if 0
+
+/* Seriously broken!!! */
+
+void
+send_bin_term(x_ei_buff* x)
+{
+ x_ei_buff x2;
+ x_ei_new(&x2);
+ x2.buff[x2.index++] = 't';
+ x_ei_append(&x2, x);
+ reply(x2.buff, x2.index);
+ free(x2.buff);
+}
+#endif
+
+/*
+ * This function sends a raw buffer of data to the
+ * Erlang side, where it will be received as {bytes, Bytes}.
+ */
+
+void
+send_buffer(buf, size)
+ char* buf; /* Buffer with bytes to send to Erlang. */
+ int size; /* Size of data to send to Erlang. */
+{
+ char* send_buf;
+
+ send_buf = (char *) malloc(size+1);
+ send_buf[0] = 'b';
+ memcpy(send_buf+1, buf, size);
+ reply(send_buf, size+1);
+ free(send_buf);
+}
+
+/***********************************************************************
+ *
+ * P r i v a t e h e l p e r s
+ *
+ ***********************************************************************/
+
+/*
+ * Sends a packet back to Erlang.
+ */
+
+static void
+reply(reply_buf, size)
+ char* reply_buf; /* Buffer with reply. */
+ unsigned size; /* Size of reply. */
+{
+ int n; /* Temporary to hold size. */
+ int i; /* Loop counter. */
+ char* buf;
+
+
+ buf = (char *) malloc(size+HEADER_SIZE);
+ memcpy(buf+HEADER_SIZE, reply_buf, size);
+
+ /*
+ * Fill the header starting with the least significant byte.
+ */
+
+ n = size;
+ for (i = HEADER_SIZE-1; i >= 0; i--) {
+ buf[i] = (char) n; /* Store least significant byte. */
+ n = n >> 8;
+ }
+
+ size += HEADER_SIZE;
+/*
+ fprintf(stderr, "\r\nReply size: %u\r\n",
+ (unsigned)buf[0] << 8 + (unsigned)buf[1]);
+
+ for (i = 0; i < size; i++) {
+ fprintf(stderr,"%u %c\r\n",buf[i],buf[i]);
+ }
+
+ fprintf(stderr, "\r\n");
+*/
+ write(fd_to_erl, buf, size);
+ free(buf);
+}
+
+
+/*
+ * Reads len number of bytes.
+ */
+
+static int
+readn(fd, buf, len)
+ int fd; /* File descriptor to read from. */
+ unsigned char *buf; /* Store in this buffer. */
+ int len; /* Number of bytes to read. */
+{
+ int n; /* Byte count in last read call. */
+ int sofar = 0; /* Bytes read so far. */
+
+ do {
+ if ((n = read(fd, buf+sofar, len-sofar)) <= 0)
+ /* error or EOF in read */
+ return(n);
+ sofar += n;
+ } while (sofar < len);
+ return sofar;
+}
+
+void
+dump(buf, sz, max)
+ unsigned char* buf;
+ int sz;
+ int max;
+{
+ int i, imax;
+ char comma[5] = ",";
+
+ if (!sz)
+ return;
+ if (sz > max)
+ imax = max;
+ else
+ imax = sz;
+
+ for (i=0; i<imax; i++) {
+ if (i == imax-1) {
+ if (sz > max)
+ strcpy(comma, ",...");
+ else
+ comma[0] = 0;
+ }
+ if (isdigit(buf[i]))
+ fprintf(stderr, "%u%s", (int)(buf[i]), comma);
+ else {
+ if (isalpha(buf[i])) {
+ fprintf(stderr, "%c%s", buf[i], comma);
+ }
+ else
+ fprintf(stderr, "%u%s", (int)(buf[i]), comma);
+ }
+ }
+}
+
diff --git a/lib/erl_interface/test/all_SUITE_data/runner.h b/lib/erl_interface/test/all_SUITE_data/runner.h
new file mode 100644
index 0000000000..fb29d5166d
--- /dev/null
+++ b/lib/erl_interface/test/all_SUITE_data/runner.h
@@ -0,0 +1,50 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include "erl_interface.h"
+
+typedef void (*TestCase)(void);
+
+#define TESTCASE(name) void name(void)
+#define ASIZE(a) (sizeof(a)/sizeof(a[0]))
+
+void run_tests(char* argv0, TestCase cases[], unsigned number);
+
+/*
+ * Reading.
+ */
+
+ETERM* get_term(void);
+char *read_packet(int *len);
+
+/*
+ * Sending replies.
+ */
+
+#define fail(reason) do_fail(__FILE__, __LINE__, reason)
+#define report(ok) do_report(__FILE__, __LINE__, ok)
+
+void do_report(char* file, int line, int ok);
+void do_fail(char* file, int line, char* reason);
+void send_term(ETERM* term);
+void send_buffer(char* buf, int size);
+void message(char* format, ...);
+
+void send_bin_term(ei_x_buff* x);
+
diff --git a/lib/erl_interface/test/ei_accept_SUITE.erl b/lib/erl_interface/test/ei_accept_SUITE.erl
new file mode 100644
index 0000000000..bc83d6a62e
--- /dev/null
+++ b/lib/erl_interface/test/ei_accept_SUITE.erl
@@ -0,0 +1,151 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_accept_SUITE).
+
+-include("test_server.hrl").
+-include("ei_accept_SUITE_data/ei_accept_test_cases.hrl").
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2,
+ ei_accept/1, ei_threaded_accept/1]).
+
+-import(runner, [get_term/1,send_term/2]).
+
+all(suite) -> [ei_accept, ei_threaded_accept].
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?t:minutes(0.25)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+ei_accept(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+
+% ?line AMsg={a,[message, with], " strings in it!", [-12, -23], 1.001},
+ %% shouldn't this be a bif or function or something?
+ ?line Myname= hd(tl(string:tokens(atom_to_list(node()), "@"))),
+ ?line io:format("Myname ~p ~n", [Myname]),
+ ?line EINode= list_to_atom("c42@"++Myname),
+ ?line io:format("EINode ~p ~n", [EINode]),
+ ?line Self= self(),
+ ?line TermToSend= {call, Self, "Test"},
+ ?line F= fun() ->
+ timer:sleep(500),
+ {any, EINode} ! TermToSend,
+ Self ! sent_ok,
+ ok
+ end,
+
+ ?line spawn(F),
+ ?line Port = 6543,
+ ?line {ok, Fd, _Node} = ei_accept(P, Port),
+ ?line TermReceived= ei_receive(P, Fd),
+ ?line io:format("Sent ~p received ~p ~n", [TermToSend, TermReceived]),
+ ?line TermToSend= TermReceived,
+ ?line receive
+ sent_ok ->
+ ok;
+ Unknown ->
+ io:format("~p ~n", [Unknown])
+ after 1000 ->
+ io:format("timeout ~n")
+ end,
+ ?line ok= ei_unpublish(P),
+ ok.
+
+ei_threaded_accept(Config) when is_list(Config) ->
+ ?line Einode = filename:join(?config(data_dir, Config), "eiaccnode"),
+ ?line N = 1, % 3,
+ ?line Host = atom_to_list(node()),
+ ?line Port = 6767,
+ ?line start_einode(Einode, N, Host, Port),
+ ?line io:format("started eiaccnode"),
+ %%?line spawn_link(fun() -> start_einode(Einode, N, Host, Port) end),
+ ?line TestServerPid = self(),
+ ?line [ spawn_link(fun() -> send_rec_einode(I, TestServerPid) end)
+ || I <- lists:seq(0, N-1) ],
+ ?line [ receive I -> ok end
+ || I <- lists:seq(0, N-1) ],
+ ok.
+
+send_rec_einode(N, TestServerPid) ->
+ ?line Myname= hd(tl(string:tokens(atom_to_list(node()), "@"))),
+ ?line EINode= list_to_atom("eiacc" ++ integer_to_list(N) ++ "@" ++ Myname),
+ ?line io:format("EINode ~p ~n", [EINode]),
+ ?line Self= self(),
+ ?line timer:sleep(10*1000),
+ ?line {any, EINode} ! Self,
+ ?line receive
+ {N,_}=X ->
+ ?line io:format("Received by ~s ~p~n", [EINode, X]),
+ ?line TestServerPid ! N,
+ ?line X
+ after 10000 ->
+ ?line test_server:fail(EINode)
+ end.
+
+start_einode(Einode, N, Host, Port) ->
+ Einodecmd = Einode ++ " " ++ atom_to_list(erlang:get_cookie())
+ ++ " " ++ integer_to_list(N) ++ " " ++ Host ++ " "
+ ++ integer_to_list(Port) ++ " nothreads",
+ io:format("Einodecmd ~p ~n", [Einodecmd]),
+ ?line open_port({spawn, Einodecmd}, []),
+ ok.
+
+
+
+%%% Interface functions for ei (erl_interface) functions.
+
+ei_connect_init(P, Num, Cookie, Creation) ->
+ send_command(P, ei_connect_init, [Num,Cookie,Creation]),
+ case get_term(P) of
+ {term,Int} when is_integer(Int) -> Int
+ end.
+
+ei_accept(P, PortNo) ->
+ send_command(P, ei_accept, [PortNo]),
+ case get_term(P) of
+ {term,{Fd, _, Node}} when Fd >= 0 -> {ok, Fd, Node};
+ {term,{_Fd, Errno, _Node}} -> {error,Errno}
+ end.
+
+ei_receive(P, Fd) ->
+ send_command(P, ei_receive, [Fd]),
+ {term, T}= get_term(P),
+ T.
+
+ei_unpublish(P) ->
+ send_command(P, ei_unpublish, []),
+ case get_term(P) of
+ {term,{0, _}} -> ok;
+ {term,{_X, Errno}} -> {error,Errno}
+ end.
+
+send_command(P, Name, Args) ->
+ runner:send_term(P, {Name,list_to_tuple(Args)}).
+
+
+
+
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..d7ec976cd0
--- /dev/null
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_accept_test_decl.c: ei_accept_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_accept_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..9b751d8f65
--- /dev/null
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/Makefile.src
@@ -0,0 +1,45 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_ACCEPT_OBJS = ei_accept_test@obj@ ei_accept_test_decl@obj@
+EIACCNODE_OBJS = eiaccnode@obj@
+
+all: ei_accept_test@exe@ eiaccnode@exe@
+
+clean:
+ $(RM) $(EI_ACCEPT_OBJS) $(EIACCNODE_OBJS)
+ $(RM) ei_accept_test@exe@ eiaccnode@exe@
+
+ei_accept_test@exe@: $(EI_ACCEPT_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_ACCEPT_OBJS) $(LIBFLAGS)
+
+
+eiaccnode@exe@: $(EIACCNODE_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EIACCNODE_OBJS) $(LIBFLAGS)
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
new file mode 100644
index 0000000000..5f898b5944
--- /dev/null
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/ei_accept_test.c
@@ -0,0 +1,224 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the accept function in ei_connect.c.
+ * Author: Jakob Cederlund (taken from erl_connect by Bj�rn Gustavsson)
+ *
+ * See the ei_accept_SUITE.erl file for a "table of contents".
+ */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef VXWORKS
+#include "reclaim.h"
+#endif
+
+#ifdef __WIN32__
+#include <winsock2.h>
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#include "ei_runner.h"
+
+static void cmd_ei_connect_init(char* buf, int len);
+static void cmd_ei_accept(char* buf, int len);
+static void cmd_ei_receive(char* buf, int len);
+static void cmd_ei_unpublish(char* buf, int len);
+
+static void send_errno_result(int value);
+
+ei_cnode ec;
+
+
+static struct {
+ char* name;
+ int num_args; /* Number of arguments. */
+ void (*func)(char* buf, int len);
+} commands[] = {
+ "ei_connect_init", 3, cmd_ei_connect_init,
+ "ei_accept", 1, cmd_ei_accept,
+ "ei_receive", 1, cmd_ei_receive,
+ "ei_unpublish", 0, cmd_ei_unpublish
+};
+
+/*
+ * Sends a list contaning all data types to the Erlang side.
+ */
+TESTCASE(interpret)
+{
+ ei_x_buff x;
+ int i;
+ ei_term term;
+
+ ei_x_new(&x);
+ for (;;) {
+ if (get_bin_term(&x, &term)) {
+ report(1);
+ return;
+ } else {
+ char* buf = x.buff, func[MAXATOMLEN];
+ int index = x.index, arity;
+ if (term.ei_type != ERL_SMALL_TUPLE_EXT || term.arity != 2)
+ fail("term should be a tuple of size 2");
+ if (ei_decode_atom(buf, &index, func) < 0)
+ fail("function name should be an atom");
+ if (ei_decode_tuple_header(buf, &index, &arity) != 0)
+ fail("function arguments should be a tuple");
+ for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
+ if (strcmp(func, commands[i].name) == 0) {
+ if (arity != commands[i].num_args)
+ fail("wrong number of arguments");
+ commands[i].func(buf + index, x.buffsz - index);
+ break;
+ }
+ }
+ if (i >= sizeof(commands)/sizeof(commands[0])) {
+ message("\"%d\" \n", func);
+ fail("bad command");
+ }
+ }
+ }
+}
+
+static void cmd_ei_connect_init(char* buf, int len)
+{
+ int index = 0, r = 0;
+ int type, size;
+ long l;
+ char b[100];
+ char cookie[MAXATOMLEN], * cp = cookie;
+ ei_x_buff res;
+ if (ei_decode_long(buf, &index, &l) < 0)
+ fail("expected int");
+ sprintf(b, "c%d", l);
+ /* FIXME don't use internal and maybe use skip?! */
+ ei_get_type_internal(buf, &index, &type, &size);
+ if (ei_decode_atom(buf, &index, cookie) < 0)
+ fail("expected atom (cookie)");
+ if (cookie[0] == '\0')
+ cp = NULL;
+ r = ei_connect_init(&ec, b, cp, 0);
+ ei_x_new_with_version(&res);
+ ei_x_encode_long(&res, r);
+ send_bin_term(&res);
+ ei_x_free(&res);
+}
+
+static int my_listen(int port)
+{
+ int listen_fd;
+ struct sockaddr_in addr;
+ const char *on = "1";
+
+ if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ return -1;
+
+ setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, on, sizeof(on));
+
+ memset((void*) &addr, 0, (size_t) sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if (bind(listen_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
+ return -1;
+
+ listen(listen_fd, 5);
+ return listen_fd;
+}
+
+static void cmd_ei_accept(char* buf, int len)
+{
+ int index = 0;
+ int listen, r;
+ ErlConnect conn;
+ long port;
+ ei_x_buff x;
+ int i;
+
+ /* get port */
+ if (ei_decode_long(buf, &index, &port) < 0)
+ fail("expected int (port)");
+ /* Make a listen socket */
+ if ((listen = my_listen(port)) <= 0)
+ fail("listen");
+
+ if ((i = ei_publish(&ec, port)) == -1)
+ fail("ei_publish");
+#ifdef VXWORKS
+ save_fd(i);
+#endif
+ r = ei_accept(&ec, listen, &conn);
+#ifdef VXWORKS
+ save_fd(r);
+#endif
+ /* send result, errno and nodename */
+ ei_x_new_with_version(&x);
+ ei_x_encode_tuple_header(&x, 3);
+ ei_x_encode_long(&x, r);
+ ei_x_encode_long(&x, erl_errno);
+ ei_x_encode_atom(&x, conn.nodename); /* or rather string? */
+ send_bin_term(&x);
+ ei_x_free(&x);
+}
+
+static void cmd_ei_receive(char* buf, int len)
+{
+ ei_x_buff x;
+ erlang_msg msg;
+ long l;
+ int fd, index = 0;
+
+ if (ei_decode_long(buf, &index, &l) < 0)
+ fail("expected int (fd)");
+ fd = l;
+ ei_x_new(&x);
+ for (;;) {
+ int got = ei_xreceive_msg(fd, &msg, &x);
+ if (got == ERL_TICK)
+ continue;
+ if (got == ERL_ERROR)
+ fail("ei_xreceive_msg");
+ break;
+ }
+ index = 1;
+ send_bin_term(&x);
+ ei_x_free(&x);
+}
+
+static void cmd_ei_unpublish(char* buf, int len)
+{
+ send_errno_result(ei_unpublish(&ec));
+}
+
+static void send_errno_result(int value)
+{
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ ei_x_encode_tuple_header(&x, 2);
+ ei_x_encode_long(&x, value);
+ ei_x_encode_long(&x, erl_errno);
+ send_bin_term(&x);
+ ei_x_free(&x);
+}
diff --git a/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
new file mode 100644
index 0000000000..af58f75963
--- /dev/null
+++ b/lib/erl_interface/test/ei_accept_SUITE_data/eiaccnode.c
@@ -0,0 +1,234 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/* to test multiple threads in ei */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __WIN32__
+#include <winsock2.h>
+#include <windows.h>
+#include <process.h>
+#else
+#ifndef VXWORKS
+#include <pthread.h>
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#include "ei.h"
+
+#ifdef VXWORKS
+#include <vxWorks.h>
+#include <sockLib.h>
+#include <inetLib.h>
+#define MAIN cnode
+#else
+#define MAIN main
+#endif
+
+static int my_listen(int port);
+
+/*
+ A small einode.
+ To be called from the test case ei_accept_SUITE:multi_thread
+ usage: eiaccnode <cookie> <n>
+
+ - start threads 0..n-1
+ - in each thread
+ - listen on "ei0" .. "ei<n-1>"
+ - wait for connection
+ - receive a pid
+ - send {i, <pid>} back
+ - shutdown gracefully
+*/
+
+static const char* cookie, * desthost;
+static int port; /* actually base port */
+
+#ifndef SD_SEND
+#ifdef SHUTWR
+#define SD_SEND SHUT_WR
+#else
+#define SD_SEND 1
+#endif
+#endif
+
+#ifndef __WIN32__
+#define closesocket(fd) close(fd)
+#endif
+
+#ifdef __WIN32__
+static DWORD WINAPI
+#else
+static void*
+#endif
+ einode_thread(void* num)
+{
+ int n = (int)num;
+ ei_cnode ec;
+ char myname[100], destname[100];
+ int r, fd, listen;
+ ErlConnect conn;
+ erlang_msg msg;
+/* FILE* f;*/
+
+ sprintf(myname, "eiacc%d", n);
+ printf("thread %d (%s) listening\n", n, myname, destname);
+ r = ei_connect_init(&ec, myname, cookie, 0);
+ if ((listen = my_listen(port+n)) <= 0) {
+ printf("listen err\n");
+ exit(7);
+ }
+ if (ei_publish(&ec, port + n) == -1) {
+ printf("ei_publish port %d\n", port+n);
+ exit(8);
+ }
+ fd = ei_accept(&ec, listen, &conn);
+ printf("ei_accept %d\n", fd);
+ if (fd >= 0) {
+ ei_x_buff x, xs;
+ int index, version;
+ erlang_pid pid;
+
+ ei_x_new(&x);
+ for (;;) {
+ int got = ei_xreceive_msg(fd, &msg, &x);
+ if (got == ERL_TICK)
+ continue;
+ if (got == ERL_ERROR) {
+ printf("receive error %d\n", n);
+ return 0;
+ }
+ printf("received %d\n", got);
+ break;
+ }
+ index = 0;
+ if (ei_decode_version(x.buff, &index, &version) != 0) {
+ printf("ei_decode_version %d\n", n);
+ return 0;
+ }
+ if (ei_decode_pid(x.buff, &index, &pid) != 0) {
+ printf("ei_decode_pid %d\n", n);
+ return 0;
+ }
+/* fprintf(f, "got pid from %s \n", pid.node);*/
+ ei_x_new_with_version(&xs);
+ ei_x_encode_tuple_header(&xs, 2);
+ ei_x_encode_long(&xs, n);
+ ei_x_encode_pid(&xs, &pid);
+ r = ei_send(fd, &pid, xs.buff, xs.index);
+/* fprintf(f, "sent %d bytes %d\n", xs.index, r);*/
+ shutdown(fd, SD_SEND);
+ closesocket(fd);
+ ei_x_free(&x);
+ ei_x_free(&xs);
+ } else {
+ printf("coudn't connect fd %d r %d\n", fd, r);
+ }
+ printf("done thread %d\n", n);
+/* fclose(f);*/
+ return 0;
+}
+
+MAIN(int argc, char *argv[])
+{
+ int i, n, no_threads;
+#ifndef VXWORKS
+#ifdef __WIN32__
+ HANDLE threads[100];
+#else
+ pthread_t threads[100];
+#endif
+#endif
+
+ if (argc < 3)
+ exit(1);
+
+ cookie = argv[1];
+ n = atoi(argv[2]);
+ if (n > 100)
+ exit(2);
+ desthost = argv[3];
+ port = atoi(argv[4]);
+#ifndef VXWORKS
+ no_threads = argv[5] != NULL && strcmp(argv[5], "nothreads") == 0;
+#else
+ no_threads = 1;
+#endif
+ for (i = 0; i < n; ++i) {
+ if (!no_threads) {
+#ifndef VXWORKS
+#ifdef __WIN32__
+ unsigned tid;
+ threads[i] = (HANDLE)_beginthreadex(NULL, 0, einode_thread,
+ (void*)i, 0, &tid);
+#else
+ pthread_create(&threads[i], NULL, einode_thread, (void*)i);
+#endif
+#else
+ ;
+#endif
+ } else
+ einode_thread((void*)i);
+ }
+
+ if (!no_threads)
+#ifndef VXWORKS
+ for (i = 0; i < n; ++i) {
+#ifdef __WIN32__
+ if (WaitForSingleObject(threads[i], INFINITE) != WAIT_OBJECT_0)
+#else
+ if (pthread_join(threads[i], NULL) != 0)
+#endif
+ printf("bad wait thread %d\n", i);
+ }
+#else
+ ;
+#endif
+ printf("ok\n");
+ return 0;
+}
+
+static int my_listen(int port)
+{
+ int listen_fd;
+ struct sockaddr_in addr;
+ const char *on = "1";
+
+ if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ return -1;
+
+ setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, on, sizeof(on));
+
+ memset((void*) &addr, 0, (size_t) sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port);
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if (bind(listen_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
+ return -1;
+
+ listen(listen_fd, 5);
+ return listen_fd;
+}
+
diff --git a/lib/erl_interface/test/ei_connect_SUITE.erl b/lib/erl_interface/test/ei_connect_SUITE.erl
new file mode 100644
index 0000000000..56f478edad
--- /dev/null
+++ b/lib/erl_interface/test/ei_connect_SUITE.erl
@@ -0,0 +1,218 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_connect_SUITE).
+
+-include("test_server.hrl").
+-include("ei_connect_SUITE_data/ei_connect_test_cases.hrl").
+
+-export([
+ all/1,
+ init_per_testcase/2,
+ fin_per_testcase/2,
+
+ ei_send/1,
+ ei_reg_send/1,
+ ei_rpc/1,
+ rpc_test/1,
+ ei_send_funs/1,
+ ei_threaded_send/1,
+ ei_set_get_tracelevel/1
+ ]).
+
+-import(runner, [get_term/1,send_term/2]).
+
+all(suite) -> [ ei_send,
+ ei_reg_send,
+ ei_rpc,
+ ei_send_funs,
+ ei_threaded_send,
+ ei_set_get_tracelevel].
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?t:minutes(0.25)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+ei_send(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = ei_connect(P, node()),
+
+ ?line ok = ei_send(P, Fd, self(), AMsg={a,message}),
+ ?line receive AMsg -> ok end,
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+ei_send_funs(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = ei_connect(P, node()),
+
+ ?line Fun1 = fun ei_send/1,
+ ?line Fun2 = fun(X) -> P, X, Fd, Fun1 end,
+
+ ?line AMsg={Fun1,Fun2},
+ %%AMsg={wait_with_funs, new_dist_format},
+ ?line ok = ei_send_funs(P, Fd, self(), AMsg),
+ ?line EIMsg = receive M -> M end,
+ ?line EIMsg = AMsg,
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+ei_reg_send(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = ei_connect(P, node()),
+
+ ARegName = a_strange_registred_name,
+ ?line register(ARegName, self()),
+ ?line ok = ei_reg_send(P, Fd, ARegName, AMsg={another,[strange],message}),
+ ?line receive AMsg -> ok end,
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+ei_threaded_send(Config) when is_list(Config) ->
+ ?line Einode = filename:join(?config(data_dir, Config), "einode"),
+ ?line N = 15,
+ ?line Host = atom_to_list(node()),
+ ?line spawn_link(fun() -> start_einode(Einode, N, Host) end),
+ ?line TestServerPid = self(),
+ ?line [ spawn_link(fun() -> rec_einode(I, TestServerPid) end)
+ || I <- lists:seq(0, N-1) ],
+ ?line [ receive I -> ok end
+ || I <- lists:seq(0, N-1) ],
+ ok.
+
+rec_einode(N, TestServerPid) ->
+ ?line Regname = list_to_atom("mth"++integer_to_list(N)),
+ ?line register(Regname, self()),
+ ?line io:format("~p waiting~n", [Regname]),
+ ?line receive
+ X ->
+ ?line io:format("Received by ~s ~p~n", [Regname, X]),
+ ?line TestServerPid ! N,
+ ?line X
+ after 10000 ->
+ ?line test_server:fail(Regname)
+ end.
+
+start_einode(Einode, N, Host) ->
+ Einodecmd = Einode ++ " " ++ atom_to_list(erlang:get_cookie())
+ ++ " " ++ integer_to_list(N) ++ " " ++ Host,
+ io:format("Einodecmd ~p ~n", [Einodecmd]),
+ ?line open_port({spawn, Einodecmd}, []),
+ ok.
+
+ei_rpc(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = ei_connect(P, node()),
+
+ ?line S= "Hej du glade!", SRev = lists:reverse(S),
+ ?line X = ei_rpc(P, Fd, self(), {?MODULE, rpc_test}, [SRev]),
+ ?line {term, S}= X,
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+ei_set_get_tracelevel(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 5 = ei_set_get_tracelevel(P, 5),
+ ?line 0 = ei_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = ei_connect(P, node()),
+
+ ?line S= "Hej du glade!", SRev = lists:reverse(S),
+ ?line X = ei_rpc(P, Fd, self(), {?MODULE, rpc_test}, [SRev]),
+ ?line {term, S}= X,
+
+ ?line 0 = ei_set_get_tracelevel(P, 0),
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%%% Interface functions for ei (erl_interface) functions.
+
+ei_connect_init(P, Num, Cookie, Creation) ->
+ send_command(P, ei_connect_init, [Num,Cookie,Creation]),
+ case get_term(P) of
+ {term,Int} when is_integer(Int) -> Int
+ end.
+
+ei_connect(P, Node) ->
+ send_command(P, ei_connect, [Node]),
+ case get_term(P) of
+ {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
+ {term,{-1,Errno}} -> {error,Errno}
+ end.
+
+ei_set_get_tracelevel(P, Tracelevel) ->
+ send_command(P, ei_set_get_tracelevel, [Tracelevel]),
+ case get_term(P) of
+ {term,{tracelevel, Level}} when is_integer(Level) -> Level
+ end.
+
+ei_send(P, Fd, To, Msg) ->
+ send_command(P, ei_send, [Fd,To,Msg]),
+ get_send_result(P).
+
+ei_send_funs(P, Fd, To, Msg) ->
+ send_command(P, ei_send_funs, [Fd,To,Msg]),
+ get_send_result(P).
+
+ei_reg_send(P, Fd, To, Msg) ->
+ send_command(P, ei_reg_send, [Fd,To,Msg]),
+ get_send_result(P).
+
+ei_rpc(P, Fd, To, Func, Msg) ->
+ send_command(P, ei_rpc, [Fd, To, Func, Msg]),
+ get_term(P).
+
+
+get_send_result(P) ->
+ case get_term(P) of
+ {term,{0,_}} -> ok;
+ {term,{1,_}} -> ok;
+ {term,{-1,Errno}} -> {error,Errno};
+ {term,{Res,Errno}}->
+ io:format("Return value: ~p\nerl_errno: ~p", [Res,Errno]),
+ ?t:fail(bad_return_value)
+ end.
+
+send_command(P, Name, Args) ->
+ runner:send_term(P, {Name,list_to_tuple(Args)}).
+
+%%% Test function for RPC
+
+rpc_test(S) ->
+ lists:reverse(S).
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..8bf22e366e
--- /dev/null
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_connect_test_decl.c: ei_connect_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_connect_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..a6525a9138
--- /dev/null
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/Makefile.src
@@ -0,0 +1,46 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_CONNECT_OBJS = ei_connect_test@obj@ ei_connect_test_decl@obj@
+EINODE_OBJS = einode@obj@
+
+all: ei_connect_test@exe@ einode@exe@
+
+clean:
+ $(RM) $(EI_CONNECT_OBJS) $(EINODE_OBJS)
+ $(RM) ei_connect_test@exe@ einode@exe@
+
+ei_connect_test@exe@: $(EI_CONNECT_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_CONNECT_OBJS) $(LIBFLAGS)
+
+
+einode@exe@: $(EINODE_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EINODE_OBJS) $(LIBFLAGS)
+
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
new file mode 100644
index 0000000000..debd3e789b
--- /dev/null
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/ei_connect_test.c
@@ -0,0 +1,289 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the functions in ei_connect.c.
+ * Author: Bjorn Gustavsson (rewritten somewhat by Jakob Cederlund)
+ *
+ * See the ei_connect_SUITE.erl file for a "table of contents".
+ */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef VXWORKS
+#include "reclaim.h"
+#endif
+
+#include "ei_runner.h"
+
+static void cmd_ei_connect_init(char* buf, int len);
+static void cmd_ei_connect(char* buf, int len);
+static void cmd_ei_send(char* buf, int len);
+static void cmd_ei_send_funs(char* buf, int len);
+static void cmd_ei_reg_send(char* buf, int len);
+static void cmd_ei_rpc(char* buf, int len);
+static void cmd_ei_set_get_tracelevel(char* buf, int len);
+
+static void send_errno_result(int value);
+
+ei_cnode ec;
+
+
+static struct {
+ char* name;
+ int num_args; /* Number of arguments. */
+ void (*func)(char* buf, int len);
+} commands[] = {
+ "ei_connect_init", 3, cmd_ei_connect_init,
+ "ei_connect", 1, cmd_ei_connect,
+ "ei_send", 3, cmd_ei_send,
+ "ei_send_funs", 3, cmd_ei_send_funs,
+ "ei_reg_send", 3, cmd_ei_reg_send,
+ "ei_rpc", 4, cmd_ei_rpc,
+ "ei_set_get_tracelevel", 1, cmd_ei_set_get_tracelevel,
+};
+
+
+/*
+ * Sends a list contaning all data types to the Erlang side.
+ */
+
+TESTCASE(interpret)
+{
+ ei_x_buff x;
+ int i;
+ ei_term term;
+
+ ei_x_new(&x);
+ for (;;) {
+ if (get_bin_term(&x, &term)) {
+ report(1);
+ return;
+ } else {
+ char* buf = x.buff, func[MAXATOMLEN];
+ int index = x.index, arity;
+ if (term.ei_type != ERL_SMALL_TUPLE_EXT || term.arity != 2)
+ fail("term should be a tuple of size 2");
+ if (ei_decode_atom(buf, &index, func) < 0)
+ fail("function name should be an atom");
+ if (ei_decode_tuple_header(buf, &index, &arity) != 0)
+ fail("function arguments should be a tuple");
+ for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
+ if (strcmp(func, commands[i].name) == 0) {
+ if (arity != commands[i].num_args)
+ fail("wrong number of arguments");
+ commands[i].func(buf + index, x.buffsz - index);
+ break;
+ }
+ }
+ if (i >= sizeof(commands)/sizeof(commands[0])) {
+ message("\"%d\" \n", func);
+ fail("bad command");
+ }
+ }
+ }
+}
+
+
+static void cmd_ei_connect_init(char* buf, int len)
+{
+ int index = 0, r = 0;
+ int type, size;
+ long l;
+ char b[100];
+ char cookie[MAXATOMLEN], * cp = cookie;
+ ei_x_buff res;
+ if (ei_decode_long(buf, &index, &l) < 0)
+ fail("expected int");
+ sprintf(b, "c%d", l);
+ /* FIXME don't use internal and maybe use skip?! */
+ ei_get_type_internal(buf, &index, &type, &size);
+ if (ei_decode_atom(buf, &index, cookie) < 0)
+ fail("expected atom (cookie)");
+ if (cookie[0] == '\0')
+ cp = NULL;
+ r = ei_connect_init(&ec, b, cp, 0);
+ ei_x_new_with_version(&res);
+ ei_x_encode_long(&res, r);
+ send_bin_term(&res);
+ ei_x_free(&res);
+}
+
+static void cmd_ei_connect(char* buf, int len)
+{
+ int index = 0;
+ char node[256];
+ int i;
+ if (ei_decode_atom(buf, &index, node) < 0)
+ fail("expected atom");
+ i=ei_connect(&ec, node);
+#ifdef VXWORKS
+ if(i >= 0) {
+ save_fd(i);
+ }
+#endif
+ send_errno_result(i);
+}
+
+static void cmd_ei_set_get_tracelevel(char* buf, int len)
+{
+ int index = 0;
+ long level = 0;
+ long ret = 0;
+ ei_x_buff x;
+
+ if (ei_decode_long(buf, &index, &level) < 0) {
+ fail("expected long");
+ }
+
+ ei_set_tracelevel((int)level);
+
+ ret = (long) ei_get_tracelevel();
+
+ ei_x_new_with_version(&x);
+ ei_x_encode_tuple_header(&x, 2);
+ ei_x_encode_atom(&x, "tracelevel");
+ ei_x_encode_long(&x, ret);
+ send_bin_term(&x);
+ ei_x_free(&x);
+}
+
+static void cmd_ei_send(char* buf, int len)
+{
+ int index = 0;
+ long fd;
+ erlang_pid pid;
+ ei_x_buff x;
+
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+ if (ei_decode_pid(buf, &index, &pid) < 0)
+ fail("expected pid (node)");
+ if (ei_x_new_with_version(&x) < 0)
+ fail("ei_x_new_with_version");
+ if (ei_x_append_buf(&x, &buf[index], len - index) < 0)
+ fail("append");
+ send_errno_result(ei_send(fd, &pid, x.buff, x.index));
+ ei_x_free(&x);
+}
+
+static void cmd_ei_send_funs(char* buf, int len)
+{
+ int index = 0, n;
+ long fd;
+ erlang_pid pid;
+ ei_x_buff x;
+ erlang_fun fun1, fun2;
+
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+ if (ei_decode_pid(buf, &index, &pid) < 0)
+ fail("expected pid (node)");
+ if (ei_decode_tuple_header(buf, &index, &n) < 0)
+ fail("expected tuple");
+ if (n != 2)
+ fail("expected tuple");
+ if (ei_decode_fun(buf, &index, &fun1) < 0)
+ fail("expected Fun1");
+ if (ei_decode_fun(buf, &index, &fun2) < 0)
+ fail("expected Fun2");
+ if (ei_x_new_with_version(&x) < 0)
+ fail("ei_x_new_with_version");
+ if (ei_x_encode_tuple_header(&x, 2) < 0)
+ fail("encode tuple header");
+ if (ei_x_encode_fun(&x, &fun1) < 0)
+ fail("encode fun1");
+ if (ei_x_encode_fun(&x, &fun2) < 0)
+ fail("encode fun2");
+ free_fun(&fun1);
+ free_fun(&fun2);
+ send_errno_result(ei_send(fd, &pid, x.buff, x.index));
+ ei_x_free(&x);
+}
+
+static void cmd_ei_reg_send(char* buf, int len)
+{
+ int index = 0;
+ long fd;
+ char reg_name[MAXATOMLEN];
+ erlang_pid pid;
+ ei_x_buff x;
+
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long (fd)");
+ if (ei_decode_atom(buf, &index, reg_name) < 0)
+ fail("expected atom (reg name)");
+ if (ei_x_new_with_version(&x) < 0)
+ fail("ei_x_new_with_version");
+ if (ei_x_append_buf(&x, &buf[index], len - index) < 0)
+ fail("append");
+ send_errno_result(ei_reg_send(&ec, fd,
+ reg_name, x.buff, x.index));
+ ei_x_free(&x);
+}
+
+static void cmd_ei_rpc(char* buf, int len)
+{
+ int index = 0, n;
+ long fd;
+ erlang_pid pid;
+ ei_x_buff x, rpc_x;
+ int r;
+ char mod[MAXATOMLEN], func[MAXATOMLEN];
+
+#if 0 && defined(__WIN32__)
+ DebugBreak();
+#endif
+
+ if (ei_decode_long(buf, &index, &fd) < 0)
+ fail("expected long");
+ if (ei_decode_pid(buf, &index, &pid) < 0)
+ fail("expected pid (node)");
+ if (ei_decode_tuple_header(buf, &index, &n) < 0 && n < 2)
+ fail("expected tuple {module, function}");
+ if (ei_decode_atom(buf, &index, mod) < 0)
+ fail("expected atom (module)");
+ if (ei_decode_atom(buf, &index, func) < 0)
+ fail("expected atom (function)");
+ message("pid %s %d %d %d\n", pid.node, pid.num, pid.serial, pid.creation);
+ message("{%s, %s}\n", mod, func);
+ if (ei_x_new(&rpc_x) < 0)
+ fail("ei_x_new");
+ if (ei_rpc(&ec, fd, mod, func, &buf[index], len - index, &rpc_x) < 0)
+ fail("ei_rpc");
+ if (ei_x_new_with_version(&x) < 0)
+ fail("ei_x_new_with_version");
+ if (ei_x_append(&x, &rpc_x) < 0)
+ fail("append");
+ send_bin_term(&x);
+ /*send_errno_result(ei_send(&ec, fd, &pid, x.buff, x.index));*/
+ ei_x_free(&x);
+ ei_x_free(&rpc_x);
+}
+
+static void send_errno_result(int value)
+{
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ ei_x_encode_tuple_header(&x, 2);
+ ei_x_encode_long(&x, value);
+ ei_x_encode_long(&x, erl_errno);
+ send_bin_term(&x);
+ ei_x_free(&x);
+}
diff --git a/lib/erl_interface/test/ei_connect_SUITE_data/einode.c b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
new file mode 100644
index 0000000000..bafe8bd5bd
--- /dev/null
+++ b/lib/erl_interface/test/ei_connect_SUITE_data/einode.c
@@ -0,0 +1,158 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/* to test multiple threads in ei */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef __WIN32__
+#include <winsock2.h>
+#include <windows.h>
+#include <process.h>
+#else
+#ifndef VXWORKS
+#include <pthread.h>
+#endif
+#include <sys/socket.h>
+#endif
+
+#include "ei.h"
+
+#ifdef VXWORKS
+#define MAIN cnode
+#else
+#define MAIN main
+#endif
+
+/*
+ A small einode.
+ To be called from the test case ei_accept_SUITE:multi_thread
+ usage: einode <cookie> <n> <destnode>
+
+ - start threads 0..n-1
+ - in each thread
+ - connect to destnode
+ - send a message ("ei0".."ei<n-1>") to mth0..mth<n-1> on destnode
+ - shutdown gracefully
+*/
+
+static const char* cookie, * desthost;
+
+#ifndef SD_SEND
+#ifdef SHUTWR
+#define SD_SEND SHUT_WR
+#else
+#define SD_SEND 1
+#endif
+#endif
+
+#ifndef __WIN32__
+#define closesocket(fd) close(fd)
+#endif
+
+#ifdef __WIN32__
+static DWORD WINAPI
+#else
+static void*
+#endif
+ einode_thread(void* num)
+{
+ int n = (int)num;
+ ei_cnode ec;
+ char myname[100], destname[100];
+ int r, fd;
+
+ sprintf(myname, "ei%d", n);
+ sprintf(destname, "mth%d", n);
+ printf("thread %d (%s %s) connecting\n", n, myname, destname);
+ r = ei_connect_init(&ec, myname, cookie, 0);
+ fd = ei_connect(&ec, (char*)desthost);
+ if (r == 0 && fd >= 0) {
+ ei_x_buff x;
+ ei_x_new_with_version(&x);
+ ei_x_encode_string(&x, myname);
+ ei_reg_send(&ec, fd, destname, x.buff, x.index);
+ ei_x_free(&x);
+ //SleepEx(100);
+ shutdown(fd, SD_SEND);
+ closesocket(fd);
+ } else {
+ printf("coudn't connect fd %d r %d\n", fd, r); // DebugBreak();
+ }
+ printf("done thread %d\n", n);
+ return 0;
+}
+
+MAIN(int argc, char *argv[])
+{
+ int i, n, no_threads;
+#ifndef VXWORKS
+#ifdef __WIN32__
+ HANDLE threads[100];
+#else
+ pthread_t threads[100];
+#endif
+#endif
+
+ if (argc < 3)
+ exit(1);
+
+ cookie = argv[1];
+ n = atoi(argv[2]);
+ if (n > 100)
+ exit(2);
+ desthost = argv[3];
+#ifndef VXWORKS
+ no_threads = argv[4] != NULL && strcmp(argv[4], "nothreads") == 0;
+#else
+ no_threads = 1;
+#endif
+ for (i = 0; i < n; ++i) {
+ if (!no_threads) {
+#ifndef VXWORKS
+#ifdef __WIN32__
+ unsigned tid;
+ threads[i] = (HANDLE)_beginthreadex(NULL, 0, einode_thread,
+ (void*)i, 0, &tid);
+#else
+ pthread_create(&threads[i], NULL, einode_thread, (void*)i);
+#endif
+#else
+ ;
+#endif
+ } else
+ einode_thread((void*)i);
+ }
+ if (!no_threads)
+#ifndef VXWORKS
+ for (i = 0; i < n; ++i) {
+#ifdef __WIN32__
+ if (WaitForSingleObject(threads[i], INFINITE) != WAIT_OBJECT_0)
+#else
+ if (pthread_join(threads[i], NULL) != 0)
+#endif
+ printf("bad wait thread %d\n", i);
+ }
+#else
+ ;
+#endif
+ printf("ok\n");
+ return 0;
+}
diff --git a/lib/erl_interface/test/ei_decode_SUITE.erl b/lib/erl_interface/test/ei_decode_SUITE.erl
new file mode 100644
index 0000000000..ea528728ab
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_SUITE.erl
@@ -0,0 +1,300 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_decode_SUITE).
+
+-include("test_server.hrl").
+-include("ei_decode_SUITE_data/ei_decode_test_cases.hrl").
+
+-export(
+ [
+ all/1,
+ 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
+ ]).
+
+all(suite) ->
+ [
+ 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
+ ].
+
+%% ---------------------------------------------------------------------------
+
+% NOTE: for historical reasons we don't pach as tight as we can,
+% we only fill 27 bits in 32 bit INTEGER_EXT
+
+
+%% ######################################################################## %%
+
+test_ei_decode_long(suite) -> [];
+test_ei_decode_long(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_decode_long),
+ send_integers(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+test_ei_decode_ulong(suite) -> [];
+test_ei_decode_ulong(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_decode_ulong),
+ send_integers(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+
+% (*) In practical terms, other values may fit into the ext format
+% i32 is signed 32 bit on C side
+% u32 is unsigned 32 bit on C side
+
+%% ######################################################################## %%
+
+test_ei_decode_longlong(suite) -> [];
+test_ei_decode_longlong(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skip,"Skipped on VxWorks"};
+ _ ->
+ ?line P = runner:start(?test_ei_decode_longlong),
+ send_integers2(P),
+ ?line runner:recv_eot(P),
+ ok
+ end.
+
+
+%% ######################################################################## %%
+
+test_ei_decode_ulonglong(suite) -> [];
+test_ei_decode_ulonglong(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skip,"Skipped on VxWorks"};
+ _ ->
+ ?line P = runner:start(?test_ei_decode_ulonglong),
+ send_integers2(P),
+ ?line runner:recv_eot(P),
+ ok
+ end.
+
+
+%% ######################################################################## %%
+%% A "character" for us is an 8 bit integer, alwasy positive, i.e.
+%% it is unsigned.
+%% FIXME maybe the API should change to use "unsigned char" to be clear?!
+
+test_ei_decode_char(suite) -> [];
+test_ei_decode_char(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_decode_char),
+
+ ?line send_term_as_binary(P,0),
+ ?line send_term_as_binary(P,16#7f),
+ ?line send_term_as_binary(P,16#ff),
+
+ ?line send_term_as_binary(P, []), % illegal type
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+test_ei_decode_nonoptimal(suite) -> [];
+test_ei_decode_nonoptimal(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_decode_nonoptimal),
+
+ send_non_optimal_pos(P), % decode_char
+ send_non_optimal(P), % decode_long
+ send_non_optimal_pos(P), % decode_ulong
+ case os:type() of
+ vxworks ->
+ ok;
+ _ ->
+ send_non_optimal(P), % decode_longlong
+ send_non_optimal_pos(P) % decode_ulonglong
+ end,
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+send_non_optimal(P) ->
+ send_non_optimal_pos(P),
+ send_non_optimal_neg(P).
+
+send_non_optimal_pos(P) ->
+ ?line send_raw(P, <<131,97,42>>),
+ ?line send_raw(P, <<131,98,42:32>>),
+ ?line send_raw(P, <<131,110,1,0,42>>),
+ ?line send_raw(P, <<131,110,2,0,42,0>>),
+ ?line send_raw(P, <<131,110,4,0,42,0,0,0>>),
+ ?line send_raw(P, <<131,111,0,0,0,1,0,42>>),
+ ?line send_raw(P, <<131,111,0,0,0,2,0,42,0>>),
+ ?line send_raw(P, <<131,111,0,0,0,3,0,42,0,0>>),
+ ?line send_raw(P, <<131,111,0,0,0,6,0,42,0,0,0,0,0>>),
+ ok.
+
+send_non_optimal_neg(P) ->
+% ?line send_raw(P, <<131,97,-42>>),
+ ?line send_raw(P, <<131,98,-42:32>>),
+ ?line send_raw(P, <<131,110,1,1,42>>),
+ ?line send_raw(P, <<131,110,2,1,42,0>>),
+ ?line send_raw(P, <<131,110,4,1,42,0,0,0>>),
+ ?line send_raw(P, <<131,111,0,0,0,1,1,42>>),
+ ?line send_raw(P, <<131,111,0,0,0,2,1,42,0>>),
+ ?line send_raw(P, <<131,111,0,0,0,3,1,42,0,0>>),
+ ?line send_raw(P, <<131,111,0,0,0,6,1,42,0,0,0,0,0>>),
+ ok.
+
+
+%% ######################################################################## %%
+
+test_ei_decode_misc(suite) -> [];
+test_ei_decode_misc(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_decode_misc),
+
+% ?line <<131>> = get_binaries(P),
+
+% ?line {term,F} = get_term(P),
+% ?line match_float(F, 0.0),
+% ?line {term,F} = get_term(P),
+% ?line match_float(F, 0.0),
+
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, -1.0),
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, -1.0),
+
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, 1.0),
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, 1.0),
+
+ ?line send_term_as_binary(P,false),
+ ?line send_term_as_binary(P,true),
+
+ ?line send_term_as_binary(P,foo),
+ ?line send_term_as_binary(P,''),
+ ?line send_term_as_binary(P,'������'),
+
+ ?line send_term_as_binary(P,"foo"),
+ ?line send_term_as_binary(P,""),
+ ?line send_term_as_binary(P,"������"),
+
+ ?line send_term_as_binary(P,<<"foo">>),
+ ?line send_term_as_binary(P,<<>>),
+ ?line send_term_as_binary(P,<<"������">>),
+
+% ?line send_term_as_binary(P,{}),
+% ?line send_term_as_binary(P,[]),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+send_term_as_binary(Port, Term) when is_port(Port) ->
+ Port ! {self(), {command, term_to_binary(Term)}}.
+
+send_raw(Port, Bin) when is_port(Port) ->
+ Port ! {self(), {command, Bin}}.
+
+
+send_integers(P) ->
+ ?line send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest
+ ?line send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest
+ ?line send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*)
+ ?line send_term_as_binary(P,-1), % INTEGER_EXT largest neg
+
+ ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT largest (28 bits)
+ ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT smallest
+ ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT smallest pos(*)
+ ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT largest neg (*)
+
+ ?line send_term_as_binary(P, 16#7fffffff), % SMALL_BIG_EXT largest i32
+ ?line send_term_as_binary(P,-16#80000000), % SMALL_BIG_EXT smallest i32
+
+ case erlang:system_info(wordsize) of
+ 4 ->
+ ?line send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32
+ ?line send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32
+
+ ?line send_term_as_binary(P, 16#7fffffffffff), % largest i48
+ ?line send_term_as_binary(P,-16#800000000000), % smallest i48
+ ?line send_term_as_binary(P, 16#ffffffffffff), % largest u48
+ ?line send_term_as_binary(P, 16#7fffffffffffffff), % largest i64
+ ?line send_term_as_binary(P,-16#8000000000000000), % smallest i64
+ ?line send_term_as_binary(P, 16#ffffffffffffffff); % largest u64
+ 8 ->
+ ?line send_term_as_binary(P, 16#8000000000000000),% SMALL_BIG_EXT u64
+ % SMALL_BIG_EXT largest u64
+ ?line send_term_as_binary(P, 16#ffffffffffffffff),
+ % largest i96
+ ?line send_term_as_binary(P, 16#7fffffffffffffffffffffff),
+ % smallest i96
+ ?line send_term_as_binary(P,-16#800000000000000000000000),
+ % largest u96
+ ?line send_term_as_binary(P, 16#ffffffffffffffffffffffff),
+ % largest i128
+ ?line send_term_as_binary(P, 16#7fffffffffffffffffffffffffffffff),
+ % smallest i128
+ ?line send_term_as_binary(P,-16#80000000000000000000000000000000),
+ % largest u128
+ ?line send_term_as_binary(P, 16#ffffffffffffffffffffffffffffffff)
+ end,
+ ?line send_term_as_binary(P, []), % illegal type
+ ok.
+
+send_integers2(P) ->
+ ?line send_term_as_binary(P,0), % SMALL_INTEGER_EXT smallest
+ ?line send_term_as_binary(P,255), % SMALL_INTEGER_EXT largest
+ ?line send_term_as_binary(P,256), % INTEGER_EXT smallest pos (*)
+ ?line send_term_as_binary(P,-1), % INTEGER_EXT largest neg
+
+ ?line send_term_as_binary(P, 16#07ffffff), % INTEGER_EXT largest (28 bits)
+ ?line send_term_as_binary(P,-16#08000000), % INTEGER_EXT smallest
+ ?line send_term_as_binary(P, 16#08000000), % SMALL_BIG_EXT smallest pos(*)
+ ?line send_term_as_binary(P,-16#08000001), % SMALL_BIG_EXT largest neg (*)
+
+ ?line send_term_as_binary(P, 16#7fffffff), % SMALL_BIG_EXT largest i32
+ ?line send_term_as_binary(P,-16#80000000), % SMALL_BIG_EXT smallest i32
+ ?line send_term_as_binary(P, 16#80000000),% SMALL_BIG_EXT u32
+ ?line send_term_as_binary(P, 16#ffffffff),% SMALL_BIG_EXT largest u32
+
+ ?line send_term_as_binary(P, 16#7fffffffffff), % largest i48
+ ?line send_term_as_binary(P,-16#800000000000), % smallest i48
+ ?line send_term_as_binary(P, 16#ffffffffffff), % largest u48
+ ?line send_term_as_binary(P, 16#7fffffffffffffff), % largest i64
+ ?line send_term_as_binary(P,-16#8000000000000000), % smallest i64
+ ?line send_term_as_binary(P, 16#ffffffffffffffff), % largest u64
+ ?line send_term_as_binary(P, []), % illegal type
+ ok.
diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..0791b54109
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_decode_test_decl.c: ei_decode_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_decode_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..76e55750c3
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/Makefile.src
@@ -0,0 +1,42 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_DECODE_OBJS = ei_decode_test@obj@ ei_decode_test_decl@obj@
+
+all: ei_decode_test@exe@
+
+clean:
+ $(RM) $(EI_DECODE_OBJS)
+ $(RM) ei_decode_test@exe@
+
+ei_decode_test@exe@: $(EI_DECODE_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_DECODE_OBJS) $(LIBFLAGS)
+
+
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
new file mode 100644
index 0000000000..d81ea88437
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_SUITE_data/ei_decode_test.c
@@ -0,0 +1,548 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifdef VXWORKS
+#include "reclaim.h"
+#endif
+
+#include "ei_runner.h"
+
+/*
+ * Purpose: Tests the ei_format() function.
+ * Author: Kent
+ */
+
+#ifdef VXWORKS
+#define MESSAGE_BACK(SIZE) \
+ message("err = %d, size2 = %d, expected size = %d", \
+ err, size1, SIZE);
+#else
+#define MESSAGE_BACK(SIZE) \
+ message("err = %d, size2 = %d, expected size = %d, long long val = %lld", \
+ err, size1, SIZE, (EI_LONGLONG)p);
+#endif
+
+#define EI_DECODE_2(FUNC,SIZE,TYPE,VAL) \
+ { \
+ TYPE p; \
+ char *buf; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #TYPE " should be " #VAL); \
+ buf = read_packet(NULL); \
+\
+ err = ei_ ## FUNC(buf+1, &size1, NULL); \
+ message("err = %d, size1 = %d, expected size = %d", \
+ err, size1, SIZE); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1 if NULL pointer"); \
+ } else { \
+ fail("returned non zero if NULL pointer"); \
+ } \
+ return; \
+ } \
+\
+ err = ei_ ## FUNC(buf+1, &size2, &p); \
+ MESSAGE_BACK(SIZE) \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1"); \
+ } else { \
+ fail("returned non zero"); \
+ } \
+ return; \
+ } \
+ if (p != (TYPE)VAL) { \
+ fail("value is not correct"); \
+ return; \
+ } \
+\
+ if (size1 != size2) { \
+ fail("size with and without pointer differs"); \
+ return; \
+ } \
+\
+ if (size1 != SIZE) { \
+ fail("size of encoded data is incorrect"); \
+ return; \
+ } \
+ } \
+
+#define EI_DECODE_2_FAIL(FUNC,SIZE,TYPE,VAL) \
+ { \
+ TYPE p, saved_p; \
+ char *buf; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #TYPE " should fail"); \
+ memset(&p,'\0',sizeof(p)); \
+ saved_p = p; \
+ buf = read_packet(NULL); \
+\
+ err = ei_ ## FUNC(buf+1, &size1, NULL); \
+ message("err = %d, size1 = %d, expected size = %d", \
+ err, size1, SIZE); \
+ if (err != -1) { \
+ fail("should return -1 if NULL pointer"); \
+ return; \
+ } \
+\
+ err = ei_ ## FUNC(buf+1, &size2, &p); \
+ message("err = %d, size2 = %d, expected size = %d", \
+ err, size1, SIZE); \
+ if (err != -1) { \
+ fail("should return -1"); \
+ return; \
+ } \
+ if (p != saved_p) { \
+ fail("p argument was modified"); \
+ return; \
+ } \
+\
+ 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_STRING(FUNC,SIZE,VAL) \
+ { \
+ char p[1024]; \
+ char *buf; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " should be " #VAL); \
+ buf = read_packet(NULL); \
+\
+ err = ei_ ## FUNC(buf+1, &size1, NULL); \
+ message("err = %d, size = %d, expected size = %d\n",err,size1,SIZE); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1 if NULL pointer"); \
+ } else { \
+ fail("returned non zero if NULL pointer"); \
+ } \
+ return; \
+ } \
+\
+ err = ei_ ## FUNC(buf+1, &size2, p); \
+ message("err = %d, size = %d, expected size = %d\n",err,size2,SIZE); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1"); \
+ } else { \
+ fail("returned non zero"); \
+ } \
+ return; \
+ } \
+\
+ if (strcmp(p,VAL) != 0) { \
+ fail("value is not correct"); \
+ return; \
+ } \
+\
+ if (size1 != size2) { \
+ fail("size with and without pointer differs"); \
+ return; \
+ } \
+\
+ if (size1 != SIZE) { \
+ fail("size of encoded data is incorrect"); \
+ return; \
+ } \
+ } \
+
+#define EI_DECODE_BIN(FUNC,SIZE,VAL,LEN) \
+ { \
+ char p[1024]; \
+ char *buf; \
+ long len; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " should be " #VAL); \
+ buf = read_packet(NULL); \
+ err = ei_ ## FUNC(buf+1, &size1, NULL, &len); \
+ message("err = %d, size = %d, len = %d, expected size = %d, expected len = %d\n",\
+ err,size1,len,SIZE,LEN); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1 if NULL pointer"); \
+ } else { \
+ fail("returned non zero"); \
+ } \
+ return; \
+ } \
+\
+ if (len != LEN) { \
+ fail("size is not correct"); \
+ return; \
+ } \
+\
+ err = ei_ ## FUNC(buf+1, &size2, p, &len); \
+ message("err = %d, size = %d, len = %d, expected size = %d, expected len = %d\n",\
+ err,size2,len,SIZE,LEN); \
+ if (err != 0) { \
+ if (err != -1) { \
+ fail("returned non zero but not -1 if NULL pointer"); \
+ } else { \
+ fail("returned non zero"); \
+ } \
+ return; \
+ } \
+\
+ if (len != LEN) { \
+ fail("size is not correct"); \
+ return; \
+ } \
+\
+ if (strncmp(p,VAL,LEN) != 0) { \
+ fail("value is not correct"); \
+ return; \
+ } \
+\
+ if (size1 != size2) { \
+ fail("size with and without pointer differs"); \
+ return; \
+ } \
+\
+ if (size1 != SIZE) { \
+ fail("size of encoded data is incorrect"); \
+ return; \
+ } \
+ } \
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_decode_long)
+{
+ EI_DECODE_2 (decode_long, 2, long, 0);
+ EI_DECODE_2 (decode_long, 2, long, 255);
+ EI_DECODE_2 (decode_long, 5, long, 256);
+ EI_DECODE_2 (decode_long, 5, long, -1);
+
+ EI_DECODE_2 (decode_long, 5, long, 0x07ffffff);
+ EI_DECODE_2 (decode_long, 5, long, -0x08000000);
+ EI_DECODE_2 (decode_long, 7, long, 0x08000000);
+ EI_DECODE_2 (decode_long, 7, long, -0x08000001);
+
+ EI_DECODE_2 (decode_long, 7, long, 0x7fffffff);
+ EI_DECODE_2 (decode_long, 7, long, -ll(0x80000000)); /* Strange :-( */
+
+ EI_DECODE_2_FAIL(decode_long, 7, long, 0x80000000);
+ EI_DECODE_2_FAIL(decode_long, 7, long, 0xffffffff);
+
+ EI_DECODE_2_FAIL(decode_long, 9, long, ll(0x7fffffffffff));
+ EI_DECODE_2_FAIL(decode_long, 9, long, -ll(0x800000000000));
+ EI_DECODE_2_FAIL(decode_long, 9, long, ll(0xffffffffffff));
+ EI_DECODE_2_FAIL(decode_long, 11, long, ll(0x7fffffffffffffff));
+ EI_DECODE_2_FAIL(decode_long, 11, long, -ll(0x8000000000000000));
+ EI_DECODE_2_FAIL(decode_long, 11, long, ll(0xffffffffffffffff));
+
+ EI_DECODE_2_FAIL(decode_long, 1, long, 0); /* Illegal type sent */
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_decode_ulong)
+{
+ EI_DECODE_2 (decode_ulong, 2, unsigned long, 0);
+ EI_DECODE_2 (decode_ulong, 2, unsigned long, 255);
+ EI_DECODE_2 (decode_ulong, 5, unsigned long, 256);
+ EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -1);
+
+ EI_DECODE_2 (decode_ulong, 5, unsigned long, 0x07ffffff);
+ EI_DECODE_2_FAIL(decode_ulong, 5, unsigned long, -0x08000000);
+ EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x08000000);
+ EI_DECODE_2_FAIL(decode_ulong, 7, unsigned long, -0x08000001);
+
+ EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x7fffffff);
+ EI_DECODE_2_FAIL(decode_ulong, 7, unsigned long, -ll(0x80000000));
+
+ if (sizeof(long) > 4) {
+ EI_DECODE_2 (decode_ulong, 11, unsigned long, ll(0x8000000000000000));
+ EI_DECODE_2 (decode_ulong, 11, unsigned long, ll(0xffffffffffffffff));
+ } else {
+ EI_DECODE_2 (decode_ulong, 7, unsigned long, 0x80000000);
+ EI_DECODE_2 (decode_ulong, 7, unsigned long, 0xffffffff);
+ }
+
+ EI_DECODE_2_FAIL(decode_ulong, 9, unsigned long, ll(0x7fffffffffff));
+ EI_DECODE_2_FAIL(decode_ulong, 9, unsigned long, -ll(0x800000000000));
+ EI_DECODE_2_FAIL(decode_ulong, 9, unsigned long, ll(0xffffffffffff));
+ EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0x7fffffffffffffff));
+ EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, -ll(0x8000000000000000));
+ EI_DECODE_2_FAIL(decode_ulong, 11, unsigned long, ll(0xffffffffffffffff));
+
+ EI_DECODE_2_FAIL(decode_ulong, 1, unsigned long, 0); /* Illegal type */
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+
+TESTCASE(test_ei_decode_longlong)
+{
+#ifndef VXWORKS
+ EI_DECODE_2 (decode_longlong, 2, EI_LONGLONG, 0);
+ EI_DECODE_2 (decode_longlong, 2, EI_LONGLONG, 255);
+ EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 256);
+ EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -1);
+
+ EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, 0x07ffffff);
+ EI_DECODE_2 (decode_longlong, 5, EI_LONGLONG, -0x08000000);
+ EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0x08000000);
+ EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, -0x08000001);
+
+ EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0x7fffffff);
+ EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, -ll(0x80000000));
+
+ EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0x80000000);
+ EI_DECODE_2 (decode_longlong, 7, EI_LONGLONG, 0xffffffff);
+
+ EI_DECODE_2 (decode_longlong, 9, EI_LONGLONG, ll(0x7fffffffffff));
+ EI_DECODE_2 (decode_longlong, 9, EI_LONGLONG, -ll(0x800000000000));
+ EI_DECODE_2 (decode_longlong, 9, EI_LONGLONG, ll(0xffffffffffff));
+ EI_DECODE_2 (decode_longlong, 11, EI_LONGLONG, ll(0x7fffffffffffffff));
+ EI_DECODE_2 (decode_longlong, 11, EI_LONGLONG, -ll(0x8000000000000000));
+ EI_DECODE_2_FAIL(decode_longlong, 11, EI_LONGLONG, ll(0xffffffffffffffff));
+
+ EI_DECODE_2_FAIL(decode_longlong, 1, EI_LONGLONG, 0); /* Illegal type */
+#endif
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_decode_ulonglong)
+{
+#ifndef VXWORKS
+ EI_DECODE_2 (decode_ulonglong, 2, EI_ULONGLONG, 0);
+ EI_DECODE_2 (decode_ulonglong, 2, EI_ULONGLONG, 255);
+ EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 256);
+ EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -1);
+
+ EI_DECODE_2 (decode_ulonglong, 5, EI_ULONGLONG, 0x07ffffff);
+ EI_DECODE_2_FAIL(decode_ulonglong, 5, EI_ULONGLONG, -0x08000000);
+ EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0x08000000);
+ EI_DECODE_2_FAIL(decode_ulonglong, 7, EI_ULONGLONG, -0x08000001);
+
+ EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0x7fffffff);
+ EI_DECODE_2_FAIL(decode_ulonglong, 7, EI_ULONGLONG, -ll(0x80000000));
+
+ EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0x80000000);
+ EI_DECODE_2 (decode_ulonglong, 7, EI_ULONGLONG, 0xffffffff);
+
+ EI_DECODE_2 (decode_ulonglong, 9, EI_ULONGLONG, ll(0x7fffffffffff));
+ EI_DECODE_2_FAIL(decode_ulonglong, 9, EI_ULONGLONG, -ll(0x800000000000));
+ EI_DECODE_2 (decode_ulonglong, 9, EI_ULONGLONG, ll(0xffffffffffff));
+ EI_DECODE_2 (decode_ulonglong,11, EI_ULONGLONG, ll(0x7fffffffffffffff));
+ EI_DECODE_2_FAIL(decode_ulonglong,11, EI_ULONGLONG, -ll(0x8000000000000000));
+ EI_DECODE_2 (decode_ulonglong,11, EI_ULONGLONG, ll(0xffffffffffffffff));
+
+ EI_DECODE_2_FAIL(decode_ulonglong, 1, EI_ULONGLONG, 0); /* Illegal type */
+#endif
+ report(1);
+}
+
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_decode_char)
+{
+ EI_DECODE_2(decode_char, 2, char, 0);
+ EI_DECODE_2(decode_char, 2, char, 0x7f);
+ EI_DECODE_2(decode_char, 2, char, 0xff);
+
+ EI_DECODE_2_FAIL(decode_char, 1, char, 0); /* Illegal type */
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_decode_nonoptimal)
+{
+ EI_DECODE_2(decode_char, 2, char, 42);
+ EI_DECODE_2(decode_char, 5, char, 42);
+ EI_DECODE_2(decode_char, 4, char, 42);
+ EI_DECODE_2(decode_char, 5, char, 42);
+ EI_DECODE_2(decode_char, 7, char, 42);
+ EI_DECODE_2(decode_char, 7, char, 42);
+ EI_DECODE_2(decode_char, 8, char, 42);
+ EI_DECODE_2(decode_char, 9, char, 42);
+ EI_DECODE_2(decode_char, 12, char, 42);
+
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+/* EI_DECODE_2(decode_char, char, -42); */
+
+ /* ---------------------------------------------------------------- */
+
+ EI_DECODE_2(decode_long, 2, long, 42);
+ EI_DECODE_2(decode_long, 5, long, 42);
+ EI_DECODE_2(decode_long, 4, long, 42);
+ EI_DECODE_2(decode_long, 5, long, 42);
+ EI_DECODE_2(decode_long, 7, long, 42);
+ EI_DECODE_2(decode_long, 7, long, 42);
+ EI_DECODE_2(decode_long, 8, long, 42);
+ EI_DECODE_2(decode_long, 9, long, 42);
+ EI_DECODE_2(decode_long, 12, long, 42);
+
+/* EI_DECODE_2(decode_long, 2, long, -42); */
+ EI_DECODE_2(decode_long, 5, long, -42);
+ EI_DECODE_2(decode_long, 4, long, -42);
+ EI_DECODE_2(decode_long, 5, long, -42);
+ EI_DECODE_2(decode_long, 7, long, -42);
+ EI_DECODE_2(decode_long, 7, long, -42);
+ EI_DECODE_2(decode_long, 8, long, -42);
+ EI_DECODE_2(decode_long, 9, long, -42);
+ EI_DECODE_2(decode_long, 12, long, -42);
+
+ /* ---------------------------------------------------------------- */
+
+ EI_DECODE_2(decode_ulong, 2, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 5, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 4, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 5, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 7, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 7, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 8, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 9, unsigned long, 42);
+ EI_DECODE_2(decode_ulong, 12, unsigned long, 42);
+
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+/* EI_DECODE_2(decode_ulong, unsigned long, -42); */
+
+ /* ---------------------------------------------------------------- */
+
+#ifndef VXWORKS
+
+ EI_DECODE_2(decode_longlong, 2, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 4, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 8, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 9, EI_LONGLONG, 42);
+ EI_DECODE_2(decode_longlong, 12, EI_LONGLONG, 42);
+
+/* EI_DECODE_2(decode_longlong, 2, EI_LONGLONG, -42); */
+ EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, -42);
+ EI_DECODE_2(decode_longlong, 4, EI_LONGLONG, -42);
+ EI_DECODE_2(decode_longlong, 5, EI_LONGLONG, -42);
+ EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, -42);
+ EI_DECODE_2(decode_longlong, 7, EI_LONGLONG, -42);
+ EI_DECODE_2(decode_longlong, 8, EI_LONGLONG, -42);
+ EI_DECODE_2(decode_longlong, 9, EI_LONGLONG, -42);
+ EI_DECODE_2(decode_longlong, 12, EI_LONGLONG, -42);
+
+ /* ---------------------------------------------------------------- */
+
+ EI_DECODE_2(decode_ulonglong, 2, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 5, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 4, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 5, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 7, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 7, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 8, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 9, EI_ULONGLONG, 42);
+ EI_DECODE_2(decode_ulonglong, 12, EI_ULONGLONG, 42);
+
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+/* EI_DECODE_2(decode_ulonglong, EI_ULONGLONG, -42); */
+
+#endif /* !VXWORKS */
+
+ /* ---------------------------------------------------------------- */
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_decode_misc)
+{
+/*
+ EI_DECODE_0(decode_version);
+*/
+/*
+ EI_DECODE_2(decode_double, 0.0);
+ EI_DECODE_2(decode_double, -1.0);
+ EI_DECODE_2(decode_double, 1.0);
+*/
+ 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_string, 6, "foo");
+ EI_DECODE_STRING(decode_string, 1, "");
+ EI_DECODE_STRING(decode_string, 9, "������");
+
+ EI_DECODE_BIN(decode_binary, 8, "foo", 3);
+ EI_DECODE_BIN(decode_binary, 5, "", 0);
+ EI_DECODE_BIN(decode_binary, 11, "������", 6);
+
+ /* FIXME check \0 in strings and atoms? */
+/*
+ EI_ENCODE_1(decode_tuple_header, 0);
+
+ EI_ENCODE_0(decode_empty_list);
+*/
+ report(1);
+}
+
+/* ******************************************************************** */
+
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE.erl b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
new file mode 100644
index 0000000000..c19c1d0887
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE.erl
@@ -0,0 +1,290 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_decode_encode_SUITE).
+
+-include("test_server.hrl").
+-include("ei_decode_encode_SUITE_data/ei_decode_encode_test_cases.hrl").
+
+-export(
+ [
+ all/1,
+ test_ei_decode_encode/1
+ ]).
+
+all(suite) ->
+ [
+ test_ei_decode_encode
+ ].
+
+%% ---------------------------------------------------------------------------
+
+% NOTE: these types have no meaning on the C side so we pass them
+% to C and back just to see they are the same.
+
+
+%% ######################################################################## %%
+
+test_ei_decode_encode(suite) -> [];
+test_ei_decode_encode(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_decode_encode),
+
+ Fun = fun (X) -> {X,true} end,
+ Pid = self(),
+ Port = case os:type() of
+ {win32,_} ->
+ open_port({spawn,"sort"},[]);
+ _ ->
+ open_port({spawn,"/bin/true"},[])
+ end,
+ Ref = make_ref(),
+ Trace = {1,2,3,self(),4}, % FIXME how to construct?!
+
+
+ BigSmallA = 1696192905348584855517250509684275447603964214606878827319923580493120589769459602596313014087329389174229999430092223701630077631205171572331191216670754029016160388576759960413039261647653627052707047,
+ BigSmallB = 43581177444506616087519351724629421082877485633442736512567383077022781906420535744195118099822189576169114064491200598595995538299156626345938812352676950427869649947439032133573270227067833308153431095,
+ BigSmallC = 52751775381034251994634567029696659541685100826881826508158083211003576763074162948462801435204697796532659535818017760528684167216110865807581759669824808936751316879636014972704885388116861127856231,
+
+ BigLargeA = 1 bsl 11111 + BigSmallA,
+ BigLargeB = 1 bsl 11112 + BigSmallB,
+ BigLargeC = BigSmallA * BigSmallB * BigSmallC * BigSmallA,
+
+ ?line send_rec(P, Fun),
+ ?line send_rec(P, Pid),
+ ?line send_rec(P, Port),
+ ?line send_rec(P, Ref),
+ ?line send_rec(P, Trace),
+
+ % bigs
+
+ ?line send_rec(P, BigSmallA),
+ ?line send_rec(P, BigSmallB),
+ ?line send_rec(P, BigSmallC),
+
+ ?line send_rec(P, BigLargeA),
+ ?line send_rec(P, BigLargeB),
+ ?line send_rec(P, BigLargeC),
+
+ %% Test large node containers...
+
+ ?line ThisNode = {node(), erlang:system_info(creation)},
+ ?line TXPid = mk_pid(ThisNode, 32767, 8191),
+ ?line TXPort = mk_port(ThisNode, 268435455),
+ ?line TXRef = mk_ref(ThisNode, [262143, 4294967295, 4294967295]),
+
+ ?line OtherNode = {gurka@sallad, 2},
+ ?line OXPid = mk_pid(OtherNode, 32767, 8191),
+ ?line OXPort = mk_port(OtherNode, 268435455),
+ ?line OXRef = mk_ref(OtherNode, [262143, 4294967295, 4294967295]),
+
+ ?line send_rec(P, TXPid),
+ ?line send_rec(P, TXPort),
+ ?line send_rec(P, TXRef),
+ ?line send_rec(P, OXPid),
+ ?line send_rec(P, OXPort),
+ ?line send_rec(P, OXRef),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+% 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]),
+ P ! {self(), {command, term_to_binary(Term)}},
+ {_B,Term} = get_buf_and_term(P).
+
+
+
+get_buf_and_term(P) ->
+ B = get_binaries(P),
+ case B of
+ <<131>> ->
+ io:format("(got single magic, no content)\n",[]),
+ {B,'$$magic$$'};
+ <<131,_>> ->
+ T = binary_to_term(B),
+ io:format("~w\n~w\n(got magic)\n",[B,T]),
+ {B,T};
+ _ ->
+ 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]),
+ {B,T}
+ end.
+
+
+get_binaries(P) ->
+ B1 = get_binary(P),
+ B2 = get_binary(P),
+ B1 = B2.
+
+get_binary(P) ->
+ case runner:get_term(P) of
+ {bytes,L} ->
+ B = list_to_binary(L),
+ io:format("~w\n",[L]),
+% For strange reasons <<131>> show up as <>....
+% io:format("~w\n",[B]),
+ B;
+ Other ->
+ Other
+ end.
+
+%%
+
+% We use our own get_term()
+
+get_term(P) ->
+ case runner:get_term(P) of
+ {bytes,[131]} ->
+ io:format("(got single magic, no content)\n",[]),
+ '$$magic$$';
+ {bytes,[131,L]} ->
+ B = list_to_binary(L),
+ T = binary_to_term(B),
+ io:format("~w\n~w\n(got magic)\n",[L,T]),
+ T;
+ {bytes,L} ->
+ B = list_to_binary([131,L]),
+ T = binary_to_term(B),
+ io:format("~w\n~w\n(got no magic)\n",[L,T]),
+ T;
+ Other ->
+ Other
+ end.
+
+%%
+%% Node container constructor functions
+%%
+
+-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,
+ (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]}).
+
+
+
+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) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ?PID_EXT,
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ 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]});
+ 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) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ?PORT_EXT,
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ uint32_be(Number),
+ uint8(Creation)])) of
+ Port when is_port(Port) ->
+ Port;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_port, [{NodeName, 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) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ?REFERENCE_EXT,
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ uint32_be(Number),
+ uint8(Creation)])) of
+ Ref when is_reference(Ref) ->
+ Ref;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_ref, [{NodeName, 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) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ?NEW_REFERENCE_EXT,
+ uint16_be(length(Numbers)),
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ uint8(Creation),
+ lists:map(fun (N) ->
+ uint32_be(N)
+ end,
+ Numbers)])) of
+ Ref when is_reference(Ref) ->
+ Ref;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]});
+ Other ->
+ exit({unexpected_binary_to_term_result, Other})
+ end.
+
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..168a21b10e
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_decode_encode_test_decl.c: ei_decode_encode_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_decode_encode_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..d43e834558
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/Makefile.src
@@ -0,0 +1,42 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_DECODE_ENCODE_OBJS = ei_decode_encode_test@obj@ ei_decode_encode_test_decl@obj@
+
+all: ei_decode_encode_test@exe@
+
+clean:
+ $(RM) $(EI_DECODE_ENCODE_OBJS)
+ $(RM) ei_decode_encode_test@exe@
+
+ei_decode_encode_test@exe@: $(EI_DECODE_ENCODE_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_DECODE_ENCODE_OBJS) $(LIBFLAGS)
+
+
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
new file mode 100644
index 0000000000..406f02ecfb
--- /dev/null
+++ b/lib/erl_interface/test/ei_decode_encode_SUITE_data/ei_decode_encode_test.c
@@ -0,0 +1,229 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifdef VXWORKS
+#include "reclaim.h"
+#endif
+
+#include "ei_runner.h"
+
+/*
+ * Purpose: Read pids, funs and others without real meaning on the C side
+ * and pass it back to Erlang to test that it is still the same.
+ * Author: [email protected]
+ */
+
+#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); \
+ }
+
+
+
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_decode_encode)
+{
+ EI_DECODE_ENCODE(fun , erlang_fun);
+ EI_DECODE_ENCODE(pid , erlang_pid);
+ EI_DECODE_ENCODE(port , erlang_port);
+ EI_DECODE_ENCODE(ref , erlang_ref);
+ EI_DECODE_ENCODE(trace, erlang_trace);
+
+ EI_DECODE_ENCODE_BIG(big , erlang_big);
+ EI_DECODE_ENCODE_BIG(big , erlang_big);
+ EI_DECODE_ENCODE_BIG(big , erlang_big);
+
+ EI_DECODE_ENCODE_BIG(big , erlang_big);
+ EI_DECODE_ENCODE_BIG(big , erlang_big);
+ EI_DECODE_ENCODE_BIG(big , erlang_big);
+
+ /* Test large node containers... */
+ EI_DECODE_ENCODE(pid , erlang_pid);
+ EI_DECODE_ENCODE(port , erlang_port);
+ EI_DECODE_ENCODE(ref , erlang_ref);
+ 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
new file mode 100644
index 0000000000..fb790eb7c3
--- /dev/null
+++ b/lib/erl_interface/test/ei_encode_SUITE.erl
@@ -0,0 +1,315 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_encode_SUITE).
+
+-include("test_server.hrl").
+-include("ei_encode_SUITE_data/ei_encode_test_cases.hrl").
+
+-export(
+ [
+ all/1,
+ test_ei_encode_long/1,
+ test_ei_encode_ulong/1,
+ test_ei_encode_longlong/1,
+ test_ei_encode_ulonglong/1,
+ test_ei_encode_char/1,
+ test_ei_encode_misc/1,
+ test_ei_encode_fails/1
+ ]).
+
+all(suite) ->
+ [
+ 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
+ ].
+
+%% ---------------------------------------------------------------------------
+
+% NOTE: for historical reasons we don't pach as tight as we can,
+% we only fill 27 bits in 32 bit INTEGER_EXT
+
+
+%% ######################################################################## %%
+
+test_ei_encode_long(suite) -> [];
+test_ei_encode_long(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_encode_long),
+
+ ?line {<<97,0>> ,0} = get_buf_and_term(P),
+ ?line {<<97,255>> ,255} = get_buf_and_term(P),
+ ?line {<<98,256:32/big-signed-integer>>,256} = get_buf_and_term(P),
+ ?line {<<98,-1:32/big-signed-integer>> ,-1} = get_buf_and_term(P),
+
+ ?line {<<98, 16#07ffffff:32/big-signed-integer>>, 16#07ffffff} = get_buf_and_term(P),
+ ?line {<<98,-16#08000000:32/big-signed-integer>>,-16#08000000} = get_buf_and_term(P),
+ ?line {<<110,4,0, 0,0,0,8>> , 16#08000000} = get_buf_and_term(P),
+ ?line {<<110,4,1, 1,0,0,8>> ,-16#08000001} = get_buf_and_term(P),
+
+ ?line {<<110,4,0, 255,255,255,127>> , 16#7fffffff} = get_buf_and_term(P),
+ ?line {<<110,4,1, 0,0,0,128>> ,-16#80000000} = get_buf_and_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+test_ei_encode_ulong(suite) -> [];
+test_ei_encode_ulong(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_encode_ulong),
+
+ ?line {<<97,0>> ,0} = get_buf_and_term(P),
+ ?line {<<97,255>> ,255} = get_buf_and_term(P),
+ ?line {<<98,256:32/big-unsigned-integer>>,256} = get_buf_and_term(P),
+
+ ?line {<<98, 16#07ffffff:32/big-signed-integer>>,16#07ffffff} = get_buf_and_term(P),
+ ?line {<<110,4,0, 0,0,0,8>> ,16#08000000} = get_buf_and_term(P),
+
+ ?line {<<110,4,0, 255,255,255,127>> ,16#7fffffff} = get_buf_and_term(P),
+ ?line {<<110,4,0, 0,0,0,128>> ,16#80000000} = get_buf_and_term(P),
+ ?line {<<110,4,0, 255,255,255,255>> ,16#ffffffff} = get_buf_and_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+test_ei_encode_longlong(suite) -> [];
+test_ei_encode_longlong(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skip,"Skipped on VxWorks"};
+ _ ->
+ ?line P = runner:start(?test_ei_encode_longlong),
+
+ ?line {<<97,0>> ,0} = get_buf_and_term(P),
+ ?line {<<97,255>> ,255} = get_buf_and_term(P),
+ ?line {<<98,256:32/big-signed-integer>>,256} = get_buf_and_term(P),
+ ?line {<<98,-1:32/big-signed-integer>> ,-1} = get_buf_and_term(P),
+
+ ?line {<<98, 16#07ffffff:32/big-signed-integer>>, 16#07ffffff} = get_buf_and_term(P),
+ ?line {<<98,-16#08000000:32/big-signed-integer>>,-16#08000000} = get_buf_and_term(P),
+ ?line {<<110,4,0, 0,0,0,8>> , 16#08000000} = get_buf_and_term(P),
+ ?line {<<110,4,1, 1,0,0,8>> ,-16#08000001} = get_buf_and_term(P),
+
+ ?line {<<110,4,0, 255,255,255,127>> , 16#7fffffff} = get_buf_and_term(P),
+ ?line {<<110,4,1, 0,0,0,128>> ,-16#80000000} = get_buf_and_term(P),
+ ?line {<<110,6,0, 255,255,255,255,255,127>> , 16#7fffffffffff} = get_buf_and_term(P),
+ ?line {<<110,6,1, 0,0,0,0,0,128>> ,-16#800000000000} = get_buf_and_term(P),
+ ?line {<<110,8,0, 255,255,255,255,255,255,255,127>>,16#7fffffffffffffff} = get_buf_and_term(P),
+ ?line {<<110,8,1, 0,0,0,0,0,0,0,128>> ,-16#8000000000000000} = get_buf_and_term(P),
+
+ ?line runner:recv_eot(P),
+ ok
+ end.
+
+
+%% ######################################################################## %%
+
+test_ei_encode_ulonglong(suite) -> [];
+test_ei_encode_ulonglong(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skip,"Skipped on VxWorks"};
+ _ ->
+ ?line P = runner:start(?test_ei_encode_ulonglong),
+
+ ?line {<<97,0>> ,0} = get_buf_and_term(P),
+ ?line {<<97,255>> ,255} = get_buf_and_term(P),
+ ?line {<<98,256:32/big-unsigned-integer>>,256} = get_buf_and_term(P),
+
+ ?line {<<98, 16#07ffffff:32/big-signed-integer>>,16#07ffffff} = get_buf_and_term(P),
+ ?line {<<110,4,0, 0,0,0,8>> ,16#08000000} = get_buf_and_term(P),
+
+ ?line {<<110,4,0, 255,255,255,127>> ,16#7fffffff} = get_buf_and_term(P),
+ ?line {<<110,4,0, 0,0,0,128>> ,16#80000000} = get_buf_and_term(P),
+ ?line {<<110,4,0, 255,255,255,255>> ,16#ffffffff} = get_buf_and_term(P),
+ ?line {<<110,6,0, 255,255,255,255,255,255>>,16#ffffffffffff} = get_buf_and_term(P),
+ ?line {<<110,8,0, 255,255,255,255,255,255,255,255>>,16#ffffffffffffffff} = get_buf_and_term(P),
+
+ ?line runner:recv_eot(P),
+ ok
+ end.
+
+
+%% ######################################################################## %%
+%% A "character" for us is an 8 bit integer, alwasy positive, i.e.
+%% it is unsigned.
+%% FIXME maybe the API should change to use "unsigned char" to be clear?!
+
+test_ei_encode_char(suite) -> [];
+test_ei_encode_char(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_encode_char),
+
+ ?line {<<97, 0>>,0} = get_buf_and_term(P),
+ ?line {<<97,127>>,16#7f} = get_buf_and_term(P),
+ ?line {<<97,255>>,16#ff} = get_buf_and_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+test_ei_encode_misc(suite) -> [];
+test_ei_encode_misc(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_encode_misc),
+
+ ?line <<131>> = get_binaries(P),
+
+% ?line {term,F} = get_term(P),
+% ?line match_float(F, 0.0),
+% ?line {term,F} = get_term(P),
+% ?line match_float(F, 0.0),
+
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, -1.0),
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, -1.0),
+
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, 1.0),
+% ?line {term,F} = get_term(P),
+% ?line true = match_float(F, 1.0),
+
+ ?line {<<100,0,5,"false">>,false} = get_buf_and_term(P),
+ ?line {<<100,0,4,"true">> ,true} = get_buf_and_term(P),
+ ?line {<<100,0,4,"true">> ,true} = get_buf_and_term(P),
+ ?line {<<100,0,4,"true">> ,true} = get_buf_and_term(P),
+
+ ?line {<<100,0,3,"foo">>,foo} = get_buf_and_term(P),
+ ?line {<<100,0,3,"foo">>,foo} = get_buf_and_term(P),
+ ?line {<<100,0,0,"">>,''} = get_buf_and_term(P),
+ ?line {<<100,0,0,"">>,''} = get_buf_and_term(P),
+ ?line {<<100,0,6,"������">>,'������'} = get_buf_and_term(P),
+ ?line {<<100,0,6,"������">>,'������'} = get_buf_and_term(P),
+
+ ?line {<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P),
+ ?line {<<107,0,3,"foo">>,"foo"} = get_buf_and_term(P),
+ ?line {<<106>>,""} = get_buf_and_term(P),
+ ?line {<<106>>,""} = get_buf_and_term(P),
+ ?line {<<107,0,6,"������">>,"������"} = get_buf_and_term(P),
+ ?line {<<107,0,6,"������">>,"������"} = get_buf_and_term(P),
+
+ ?line {<<109,0,0,0,3,"foo">>,<<"foo">>} = get_buf_and_term(P),
+ ?line {<<109,0,0,0,0,"">>,<<>>} = get_buf_and_term(P),
+ ?line {<<109,0,0,0,6,"������">>,<<"������">>} = get_buf_and_term(P),
+
+ ?line {<<104,0>>,{}} = get_buf_and_term(P), % Tuple header for {}
+ ?line {<<106>>,[]} = get_buf_and_term(P), % Empty list []
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% ######################################################################## %%
+
+test_ei_encode_fails(suite) -> [];
+test_ei_encode_fails(Config) when is_list(Config) ->
+ ?line P = runner:start(?test_ei_encode_fails),
+
+ ?line XAtom = list_to_atom(lists:duplicate(255, $x)),
+ ?line YAtom = list_to_atom(lists:duplicate(255, $y)),
+
+ ?line XAtom = get_term(P),
+ ?line XAtom = get_term(P),
+ ?line YAtom = get_term(P),
+ ?line YAtom = get_term(P),
+
+ ?line {{{{}}}} = get_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) ->
+ B = get_binaries(P),
+ case B of
+ <<131>> ->
+ io:format("(got single magic, no content)\n",[]),
+ {B,'$$magic$$'};
+ <<131,_>> ->
+ T = binary_to_term(B),
+ io:format("~w\n~w\n(got magic)\n",[B,T]),
+ {B,T};
+ _ ->
+ 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]),
+ {B,T}
+ end.
+
+
+get_binaries(P) ->
+ B1 = get_binary(P),
+ B2 = get_binary(P),
+ B1 = B2.
+
+get_binary(P) ->
+ case runner:get_term(P) of
+ {bytes,L} ->
+ B = list_to_binary(L),
+ io:format("~w\n",[L]),
+% For strange reasons <<131>> show up as <>....
+% io:format("~w\n",[B]),
+ B;
+ Other ->
+ Other
+ end.
+
+%%
+
+% We use our own get_term()
+
+get_term(P) ->
+ case runner:get_term(P) of
+ {bytes,[131]} ->
+ io:format("(got single magic, no content)\n",[]),
+ '$$magic$$';
+ {bytes,[131,L]} ->
+ B = list_to_binary(L),
+ T = binary_to_term(B),
+ io:format("~w\n~w\n(got magic)\n",[L,T]),
+ T;
+ {bytes,L} ->
+ B = list_to_binary([131,L]),
+ T = binary_to_term(B),
+ io:format("~w\n~w\n(got no magic)\n",[L,T]),
+ T;
+ Other ->
+ Other
+ end.
+
+%%
+
+match_float(F, Match) when is_float(F), F > Match*0.99, F < Match*1.01 ->
+ true.
+
diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..19a6f4c0aa
--- /dev/null
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_encode_test_decl.c: ei_encode_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_encode_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..f2a2c40615
--- /dev/null
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/Makefile.src
@@ -0,0 +1,42 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_ENCODE_OBJS = ei_encode_test@obj@ ei_encode_test_decl@obj@
+
+all: ei_encode_test@exe@
+
+clean:
+ $(RM) $(EI_ENCODE_OBJS)
+ $(RM) ei_encode_test@exe@
+
+ei_encode_test@exe@: $(EI_ENCODE_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_ENCODE_OBJS) $(LIBFLAGS)
+
+
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
new file mode 100644
index 0000000000..f8de0b7878
--- /dev/null
+++ b/lib/erl_interface/test/ei_encode_SUITE_data/ei_encode_test.c
@@ -0,0 +1,466 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2004-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifdef VXWORKS
+#include "reclaim.h"
+#endif
+
+#include "ei_runner.h"
+
+/*
+ * Purpose: Tests the ei_format() function.
+ * Author: Kent
+ */
+
+#define EI_ENCODE_0(FUNC) \
+ { \
+ char buf[1024]; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " encoded as "); \
+ err = ei_ ## FUNC(NULL, &size1); \
+ 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); \
+ 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 " encoded as "); \
+ ei_x_new(&arg); \
+ err = ei_x_ ## FUNC(&arg); \
+ 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_1(FUNC,ARG) \
+ { \
+ char buf[1024]; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #ARG " encoded as "); \
+ err = ei_ ## FUNC(NULL, &size1, ARG); \
+ 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, ARG); \
+ 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 " " #ARG " encoded as "); \
+ ei_x_new(&arg); \
+ err = ei_x_ ## FUNC(&arg, ARG); \
+ 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_2(FUNC,ARG1,ARG2) \
+ { \
+ char buf[1024]; \
+ int size1 = 0; \
+ int size2 = 0; \
+ int err; \
+ message("ei_" #FUNC " " #ARG1 " " #ARG2 " encoded as "); \
+ err = ei_ ## FUNC(NULL, &size1, ARG1, ARG2); \
+ 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); \
+ 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 " encoded as "); \
+ ei_x_new(&arg); \
+ err = ei_x_ ## FUNC(&arg, ARG1, ARG2); \
+ 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); \
+ }
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_encode_long)
+{
+ EI_ENCODE_1(encode_long, 0);
+
+ EI_ENCODE_1(encode_long, 255);
+
+ EI_ENCODE_1(encode_long, 256);
+
+ EI_ENCODE_1(encode_long, -1);
+
+ EI_ENCODE_1(encode_long, 0x07ffffff);
+
+ EI_ENCODE_1(encode_long, -ll(0x08000000));
+
+ EI_ENCODE_1(encode_long, 0x07ffffff+1);
+
+ EI_ENCODE_1(encode_long, -ll(0x08000000)-1);
+
+ EI_ENCODE_1(encode_long, 0x7fffffff);
+
+ EI_ENCODE_1(encode_long, -ll(0x80000000));
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_encode_ulong)
+{
+ EI_ENCODE_1(encode_ulong, 0);
+
+ EI_ENCODE_1(encode_ulong, 255);
+
+ EI_ENCODE_1(encode_ulong, 256);
+
+ EI_ENCODE_1(encode_ulong, 0x07ffffff);
+
+ EI_ENCODE_1(encode_ulong, 0x07ffffff+1);
+
+ EI_ENCODE_1(encode_ulong, 0x7fffffff);
+
+ EI_ENCODE_1(encode_ulong, 0x80000000);
+
+ EI_ENCODE_1(encode_ulong, 0xffffffff);
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+
+TESTCASE(test_ei_encode_longlong)
+{
+
+#ifndef VXWORKS
+
+ EI_ENCODE_1(encode_longlong, 0);
+
+ EI_ENCODE_1(encode_longlong, 255);
+
+ EI_ENCODE_1(encode_longlong, 256);
+
+ EI_ENCODE_1(encode_longlong, -1);
+
+ EI_ENCODE_1(encode_longlong, 0x07ffffff);
+
+ EI_ENCODE_1(encode_longlong, -ll(0x08000000));
+
+ EI_ENCODE_1(encode_longlong, 0x07ffffff+1);
+
+ EI_ENCODE_1(encode_longlong, -ll(0x08000000)-1);
+
+ EI_ENCODE_1(encode_longlong, 0x7fffffff);
+
+ EI_ENCODE_1(encode_longlong, -ll(0x80000000));
+
+ EI_ENCODE_1(encode_longlong, ll(0x7fffffffffff));
+
+ EI_ENCODE_1(encode_longlong, -ll(0x800000000000));
+
+ EI_ENCODE_1(encode_longlong, ll(0x7fffffffffffffff));
+
+ EI_ENCODE_1(encode_longlong, -ll(0x8000000000000000));
+
+#endif /* !VXWORKS */
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_encode_ulonglong)
+{
+
+#ifndef VXWORKS
+
+ EI_ENCODE_1(encode_ulonglong, 0);
+
+ EI_ENCODE_1(encode_ulonglong, 255);
+
+ EI_ENCODE_1(encode_ulonglong, 256);
+
+ EI_ENCODE_1(encode_ulonglong, 0x07ffffff);
+
+ EI_ENCODE_1(encode_ulonglong, 0x07ffffff+1);
+
+ EI_ENCODE_1(encode_ulonglong, 0x7fffffff);
+
+ EI_ENCODE_1(encode_ulonglong, 0x80000000);
+
+ EI_ENCODE_1(encode_ulonglong, 0xffffffff);
+
+ EI_ENCODE_1(encode_ulonglong, ll(0xffffffffffff));
+
+ EI_ENCODE_1(encode_ulonglong, ll(0xffffffffffffffff));
+
+#endif /* !VXWORKS */
+
+ report(1);
+}
+
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_encode_char)
+{
+ EI_ENCODE_1(encode_char, 0);
+
+ EI_ENCODE_1(encode_char, 0x7f);
+
+ EI_ENCODE_1(encode_char, 0xff);
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_encode_misc)
+{
+ EI_ENCODE_0(encode_version);
+/*
+ EI_ENCODE_1(encode_double, 0.0);
+
+ EI_ENCODE_1(encode_double, -1.0);
+
+ EI_ENCODE_1(encode_double, 1.0);
+*/
+ EI_ENCODE_1(encode_boolean, 0) /* Only case it should be false */;
+
+ EI_ENCODE_1(encode_boolean, 1);
+
+ EI_ENCODE_1(encode_boolean, 42);
+
+ EI_ENCODE_1(encode_boolean, -1);
+
+ EI_ENCODE_1(encode_atom, "foo");
+ EI_ENCODE_2(encode_atom_len, "foo", 3);
+
+ EI_ENCODE_1(encode_atom, "");
+ EI_ENCODE_2(encode_atom_len, "", 0);
+
+ EI_ENCODE_1(encode_atom, "������");
+ EI_ENCODE_2(encode_atom_len, "������", 6);
+
+ EI_ENCODE_1(encode_string, "foo");
+ EI_ENCODE_2(encode_string_len, "foo", 3);
+
+ EI_ENCODE_1(encode_string, "");
+ EI_ENCODE_2(encode_string_len, "", 0);
+
+ EI_ENCODE_1(encode_string, "������");
+ EI_ENCODE_2(encode_string_len, "������", 6);
+
+ EI_ENCODE_2(encode_binary, "foo", 3);
+ EI_ENCODE_2(encode_binary, "", 0);
+ EI_ENCODE_2(encode_binary, "������", 6);
+
+ /* FIXME check \0 in strings and atoms */
+
+ EI_ENCODE_1(encode_tuple_header, 0);
+
+ EI_ENCODE_0(encode_empty_list);
+
+ report(1);
+}
+
+/* ******************************************************************** */
+
+TESTCASE(test_ei_encode_fails)
+{
+ char buf[1024];
+ int index;
+
+ /* FIXME the ei_x versions are not tested */
+
+ index = 0;
+ if (ei_encode_atom(buf, &index, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") != 0) {
+ fail("could not encode atom with 255 chars");
+ }
+ message("Encoding atom with 255 chars, encoded %d",index);
+ if (index != 255+3) {
+ fail("encoded with incorrect size");
+ }
+ send_buffer(buf, index);
+
+ index = 0;
+ if (ei_encode_atom_len(buf, &index, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 255) != 0) {
+ fail("could not encode atom with 255 chars");
+ }
+ message("Encoding atom with 255 chars, encoded %d",index);
+ if (index != 255+3) {
+ fail("encoded with incorrect size");
+ }
+ send_buffer(buf, index);
+
+ index = 0;
+ if (ei_encode_atom(buf, &index, "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy") != 0) {
+ fail("could not encode atom with 256 chars, truncated to 255");
+ }
+ message("Encoding atom with 256 chars, encoded %d",index);
+ if (index != 255+3) {
+ fail("did not truncate at 255 chars");
+ }
+ send_buffer(buf, index);
+
+ index = 0;
+ if (ei_encode_atom_len(buf, &index, "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy", 256) != 0) {
+ fail("could not encode atom with 256 chars, truncated to 255");
+ }
+ message("Encoding atom with 256 chars, encoded %d",index);
+ if (index != 255+3) {
+ fail("did not truncate at 255 chars");
+ }
+ send_buffer(buf, index);
+
+ /* ---------------------------------------------------------------------- */
+
+ index = 0;
+ if (ei_encode_tuple_header(buf, &index, 1) != 0) {
+ fail("could not create tuple header arity 1, take 1");
+ }
+ if (ei_encode_tuple_header(buf, &index, 1) != 0) {
+ fail("could not create tuple header arity 1, take 2");
+ }
+ if (ei_encode_tuple_header(buf, &index, 1) != 0) {
+ fail("could not create tuple header arity 1, take 3");
+ }
+ if (ei_encode_tuple_header(buf, &index, 0) != 0) {
+ fail("could not create tuple header arity 0");
+ }
+ send_buffer(buf, index);
+
+ report(1);
+}
diff --git a/lib/erl_interface/test/ei_format_SUITE.erl b/lib/erl_interface/test/ei_format_SUITE.erl
new file mode 100644
index 0000000000..7871f07ae9
--- /dev/null
+++ b/lib/erl_interface/test/ei_format_SUITE.erl
@@ -0,0 +1,161 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_format_SUITE).
+
+-include("test_server.hrl").
+-include("ei_format_SUITE_data/ei_format_test_cases.hrl").
+
+-export([
+ format_wo_ver/1,
+ all/1,
+ atoms/1,
+ tuples/1,
+ lists/1
+ ]).
+
+-import(runner, [get_term/1]).
+
+%% This test suite test the erl_format() function.
+%% It uses the port program "ei_format_test".
+
+all(suite) -> [
+ format_wo_ver,
+ atoms,
+ tuples,
+ lists
+ ].
+
+%% Tests formatting various atoms.
+
+atoms(suite) -> [];
+atoms(Config) when is_list(Config) ->
+ ?line P = runner:start(?atoms),
+
+ ?line {term, ''} = get_term(P),
+ ?line {term, 'a'} = get_term(P),
+ ?line {term, 'A'} = get_term(P),
+ ?line {term, 'abc'} = get_term(P),
+ ?line {term, 'Abc'} = get_term(P),
+ ?line {term, 'ab@c'} = get_term(P),
+ ?line {term, 'The rain in Spain stays mainly in the plains'} =
+ get_term(P),
+
+ ?line {term, a} = get_term(P),
+ ?line {term, ab} = get_term(P),
+ ?line {term, abc} = get_term(P),
+ ?line {term, ab@c} = get_term(P),
+ ?line {term, abcdefghijklmnopq} = get_term(P),
+
+ ?line {term, ''} = get_term(P),
+ ?line {term, 'a'} = get_term(P),
+ ?line {term, 'A'} = get_term(P),
+ ?line {term, 'abc'} = get_term(P),
+ ?line {term, 'Abc'} = get_term(P),
+ ?line {term, 'ab@c'} = get_term(P),
+ ?line {term, 'The rain in Spain stays mainly in the plains'} =
+ get_term(P),
+
+ ?line {term, a} = get_term(P),
+ ?line {term, ab} = get_term(P),
+ ?line {term, abc} = get_term(P),
+ ?line {term, ab@c} = get_term(P),
+ ?line {term, ' abcdefghijklmnopq '} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+%% Tests formatting various tuples
+
+tuples(suite) -> [];
+tuples(Config) when is_list(Config) ->
+ ?line P = runner:start(?tuples),
+
+ ?line {term, {}} = get_term(P),
+ ?line {term, {a}} = get_term(P),
+ ?line {term, {a, b}} = get_term(P),
+ ?line {term, {a, b, c}} = get_term(P),
+ ?line {term, {1}} = get_term(P),
+ ?line {term, {[]}} = get_term(P),
+ ?line {term, {[], []}} = get_term(P),
+ ?line {term, {[], a, b, c}} = get_term(P),
+ ?line {term, {[], a, [], b, c}} = get_term(P),
+ ?line {term, {[], a, '', b, c}} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+%% Tests formatting various lists
+
+lists(suite) -> [];
+lists(Config) when is_list(Config) ->
+ ?line P = runner:start(?lists),
+
+ ?line {term, []} = get_term(P),
+ ?line {term, [a]} = get_term(P),
+ ?line {term, [a, b]} = get_term(P),
+ ?line {term, [a, b, c]} = get_term(P),
+ ?line {term, [1]} = get_term(P),
+ ?line {term, [[]]} = get_term(P),
+ ?line {term, [[], []]} = get_term(P),
+ ?line {term, [[], a, b, c]} = get_term(P),
+ ?line {term, [[], a, [], b, c]} = get_term(P),
+ ?line {term, [[], a, '', b, c]} = get_term(P),
+ ?line {term, [[x, 2], [y, 3], [z, 4]]}= get_term(P),
+ ?line {term, [{a,b},{c,d}]}= get_term(P),
+%% ?line {term, [{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]} =
+%% get_term(P),
+
+ ?line {term, [{pi, F1}, {'cos(70)', F2}]} = get_term(P),
+ %% don't match floats directly
+ true= abs(3.1415-F1) < 0.01,
+ true= abs(0.34202-F2) < 0.01,
+
+ ?line {term, [[pi, F3], ['cos(70)', F4]]} = get_term(P),
+ true= abs(3.1415-F3) < 0.01,
+ true= abs(0.34202-F4) < 0.01,
+
+
+%% ?line {term, [[pi, 3.1415], [], ["cos(70)", 0.34202]]} = get_term(P),
+ ?line {term, [-1]} = get_term(P),
+ ?line {term, "hejsan"} = get_term(P),
+
+
+ ?line Str1 = lists:duplicate(65535,$A),
+ ?line Str2 = lists:duplicate(65536,$A),
+ ?line {term,Str1} = get_term(P),
+ ?line {term,Str2} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+format_wo_ver(suite) -> [];
+format_wo_ver(Config) when is_list(Config) ->
+ ?line P = runner:start(?format_wo_ver),
+
+ ?line {term, [{a, "b"}, {c, 10}]} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..1247ce08c7
--- /dev/null
+++ b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_format_test_decl.c: ei_format_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_format_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..73d51794e9
--- /dev/null
+++ b/lib/erl_interface/test/ei_format_SUITE_data/Makefile.src
@@ -0,0 +1,42 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_FORMAT_OBJS = ei_format_test@obj@ ei_format_test_decl@obj@
+
+all: ei_format_test@exe@
+
+clean:
+ $(RM) $(EI_FORMAT_OBJS)
+ $(RM) ei_format_test@exe@
+
+ei_format_test@exe@: $(EI_FORMAT_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_FORMAT_OBJS) $(LIBFLAGS)
+
+
diff --git a/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
new file mode 100644
index 0000000000..a969ded3dc
--- /dev/null
+++ b/lib/erl_interface/test/ei_format_SUITE_data/ei_format_test.c
@@ -0,0 +1,184 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifdef VXWORKS
+#include "reclaim.h"
+#endif
+
+#include "ei_runner.h"
+
+/*
+ * Purpose: Tests the ei_format() function.
+ * Author: Jakob
+ */
+
+static void
+send_format2(char* format, char* p)
+{
+ ei_x_buff x;
+ ei_x_new(&x);
+ ei_x_format(&x, format, p);
+ send_bin_term(&x);
+ free(x.buff);
+}
+
+static void
+send_format(char* format)
+{
+ send_format2(format, NULL);
+}
+
+TESTCASE(atoms)
+{
+ send_format("''");
+ send_format("'a'");
+ send_format("'A'");
+ send_format("'abc'");
+ send_format("'Abc'");
+ send_format("'ab@c'");
+ send_format("'The rain in Spain stays mainly in the plains'");
+
+ send_format("a");
+ send_format("ab");
+ send_format("abc");
+ send_format("ab@c");
+ send_format(" abcdefghijklmnopq ");
+
+ send_format2("~a", "");
+ send_format2("~a", "a");
+ send_format2("~a", "A");
+ send_format2("~a", "abc");
+ send_format2("~a", "Abc");
+ send_format2("~a", "ab@c");
+ send_format2("~a", "The rain in Spain stays mainly in the plains");
+
+ send_format2("~a", "a");
+ send_format2("~a", "ab");
+ send_format2("~a", "abc");
+ send_format2("~a","ab@c");
+ send_format2("~a", " abcdefghijklmnopq ");
+
+
+ report(1);
+}
+
+TESTCASE(tuples)
+{
+ send_format("{}");
+ send_format("{a}");
+ send_format("{a, b}");
+ send_format("{a, b, c}");
+ send_format("{1}");
+ send_format("{[]}");
+ send_format("{[], []}");
+ send_format("{[], a, b, c}");
+ send_format("{[], a, [], b, c}");
+ send_format("{[], a, '', b, c}");
+
+ report(1);
+}
+
+
+
+TESTCASE(lists)
+{
+/* FIXME cases to add?
+ ETERM* a;
+ ETERM* b;
+ ETERM* c;
+*/
+ ei_x_buff x;
+ static char str[65537];
+
+ send_format("[]");
+ send_format("[a]");
+ send_format("[a, b]");
+ send_format("[a, b, c]");
+ send_format("[1]");
+ send_format("[[]]");
+ send_format("[[], []]");
+ send_format("[[], a, b, c]");
+ send_format("[[], a, [], b, c]");
+ send_format("[[], a, '', b, c]");
+ send_format("[[x, 2], [y, 3], [z, 4]]");
+ send_format("[{a,b},{c,d}]"); /* OTP-4777 */
+
+ ei_x_new(&x);
+/*
+ b = erl_format("[{addr, ~s, ~i}]", "E-street", 42);
+ a = ei_format(x, "[{name, ~a}, {age, ~i}, {data, ~w}]", "Madonna", 21, b);
+ send_bin_term(a);
+ erl_free_term(b);*/
+ ei_x_format(&x, "[{pi, ~f}, {'cos(70)', ~f}]", (float)3.1415, (float)0.34202);
+ send_bin_term(&x);
+ x.index = 0; /* otherwise it'll send the previous term again */
+ ei_x_format(&x, "[[pi, ~d], ['cos(70)', ~d]]", 3.1415, 0.34202);
+ send_bin_term(&x);
+
+/* a = erl_mk_float(3.1415);
+ b = erl_mk_float(0.34202);
+ send_bin_term(ei_format("[[pi, ~w], ['cos(70)', ~w]]", a, b));
+ erl_free_term(a);
+ erl_free_term(b);
+
+ a = erl_mk_float(3.1415);
+ b = erl_mk_float(0.34202);
+ c = erl_mk_empty_list();
+ send_bin_term(ei_format("[[~a, ~w], ~w, [~s, ~w]]", "pi", a, c, "cos(70)", b));
+ erl_free_term(a);
+ erl_free_term(b);
+ erl_free_term(c);
+*/
+ x.index = 0; /* otherwise it'll send the previous term again */
+ ei_x_format(&x, "[~i]", -1);
+ send_bin_term(&x);
+
+ x.index = 0;
+ ei_x_format(&x, "~s","hejsan");
+ send_bin_term(&x);
+
+ memset(str,'A',65535);
+ str[65535] = '\0';
+ str[65536] = '\0';
+ x.index = 0;
+ ei_x_format(&x, "~s",str);
+ send_bin_term(&x);
+ str[65535] = 'A';
+ x.index = 0;
+ ei_x_format(&x, "~s",str);
+ send_bin_term(&x);
+
+
+ free(x.buff);
+ report(1);
+}
+
+TESTCASE(format_wo_ver) {
+/* OTP-6795
+ * make example with format_wo_ver
+ */
+ ei_x_buff x;
+
+ ei_x_new (&x);
+ ei_x_format(&x, "[{~a,~s},{~a,~i}]", "a", "b", "c", 10);
+ send_bin_term(&x);
+
+ free(x.buff);
+ report(1);
+}
diff --git a/lib/erl_interface/test/ei_print_SUITE.erl b/lib/erl_interface/test/ei_print_SUITE.erl
new file mode 100644
index 0000000000..a0f15338c6
--- /dev/null
+++ b/lib/erl_interface/test/ei_print_SUITE.erl
@@ -0,0 +1,142 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_print_SUITE).
+
+-include("test_server.hrl").
+-include("ei_print_SUITE_data/ei_print_test_cases.hrl").
+
+-export([all/1, atoms/1, tuples/1, lists/1, strings/1]).
+
+-import(runner, [get_term/1]).
+
+%% This test suite test the ei_print() function.
+%% It uses the port program "ei_format_test".
+
+all(suite) -> [atoms, tuples, lists, strings].
+
+%% Tests formatting various atoms.
+
+atoms(suite) -> [];
+atoms(Config) when is_list(Config) ->
+ ?line P = runner:start(?atoms),
+
+ ?line {term, "''"} = get_term(P),
+ ?line {term, "a"} = get_term(P),
+ ?line {term, "'A'"} = get_term(P),
+ ?line {term, "abc"} = get_term(P),
+ ?line {term, "'Abc'"} = get_term(P),
+ ?line {term, "ab@c"} = get_term(P),
+ ?line {term, "'The rain in Spain stays mainly in the plains'"} =
+ get_term(P),
+
+ ?line {term, "a"} = get_term(P),
+ ?line {term, "ab"} = get_term(P),
+ ?line {term, "abc"} = get_term(P),
+ ?line {term, "ab@c"} = get_term(P),
+ ?line {term, "abcdefghijklmnopq"} = get_term(P),
+
+ ?line {term, "''"} = get_term(P),
+ ?line {term, "a"} = get_term(P),
+ ?line {term, "'A'"} = get_term(P),
+ ?line {term, "abc"} = get_term(P),
+ ?line {term, "'Abc'"} = get_term(P),
+ ?line {term, "ab@c"} = get_term(P),
+ ?line {term, "'The rain in Spain stays mainly in the plains'"} =
+ get_term(P),
+
+ ?line {term, "a"} = get_term(P),
+ ?line {term, "ab"} = get_term(P),
+ ?line {term, "abc"} = get_term(P),
+ ?line {term, "ab@c"} = get_term(P),
+ ?line {term, "' abcdefghijklmnopq '"} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+%% Tests formatting various tuples
+
+tuples(suite) -> [];
+tuples(Config) when is_list(Config) ->
+ ?line P = runner:start(?tuples),
+
+ ?line {term, "{}"} = get_term(P),
+ ?line {term, "{a}"} = get_term(P),
+ ?line {term, "{a, b}"} = get_term(P),
+ ?line {term, "{a, b, c}"} = get_term(P),
+ ?line {term, "{1}"} = get_term(P),
+ ?line {term, "{[]}"} = get_term(P),
+ ?line {term, "{[], []}"} = get_term(P),
+ ?line {term, "{[], a, b, c}"} = get_term(P),
+ ?line {term, "{[], a, [], b, c}"} = get_term(P),
+ ?line {term, "{[], a, '', b, c}"} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+%% Tests formatting various lists
+
+lists(suite) -> [];
+lists(Config) when is_list(Config) ->
+ ?line P = runner:start(?lists),
+
+ ?line {term, "[]"} = get_term(P),
+ ?line {term, "[a]"} = get_term(P),
+ ?line {term, "[a, b]"} = get_term(P),
+ ?line {term, "[a, b, c]"} = get_term(P),
+ ?line {term, "[1]"} = get_term(P),
+ ?line {term, "[[]]"} = get_term(P),
+ ?line {term, "[[], []]"} = get_term(P),
+ ?line {term, "[[], a, b, c]"} = get_term(P),
+ ?line {term, "[[], a, [], b, c]"} = get_term(P),
+ ?line {term, "[[], a, '', b, c]"} = get_term(P),
+ ?line {term, "[[x, 2], [y, 3], [z, 4]]"}= get_term(P),
+
+%% ?line {term, "[{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]"} =
+%% get_term(P),
+ %% kanske regexp i st�llet?
+ ?line {term, "[{pi, 3.141500}, {'cos(70)', 0.342020}]"} = get_term(P),
+ ?line {term, "[[pi, 3.141500], ['cos(70)', 0.342020]]"} = get_term(P),
+
+ ?line {term, "[-1]"} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+strings(suite) -> [];
+strings(Config) when is_list(Config) ->
+ ?line P = runner:start(?strings),
+
+ ?line {term, "\"\\n\""} = get_term(P),
+ ?line {term, "\"\\r\\n\""} = get_term(P),
+ ?line {term, "\"a\""} = get_term(P),
+ ?line {term, "\"A\""} = get_term(P),
+ ?line {term, "\"0\""} = get_term(P),
+ ?line {term, "\"9\""} = get_term(P),
+ ?line {term, "\"The rain in Spain stays mainly in the plains\""} = get_term(P),
+ ?line {term, "\" abcdefghijklmnopq \""} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..e36d4364dc
--- /dev/null
+++ b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_print_test_decl.c: ei_print_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_print_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..6eec4b1990
--- /dev/null
+++ b/lib/erl_interface/test/ei_print_SUITE_data/Makefile.src
@@ -0,0 +1,42 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_PRINT_OBJS = ei_print_test@obj@ ei_print_test_decl@obj@
+
+all: ei_print_test@exe@
+
+clean:
+ $(RM) $(EI_PRINT_OBJS)
+ $(RM) ei_print_test@exe@
+
+ei_print_test@exe@: $(EI_PRINT_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_PRINT_OBJS) $(LIBFLAGS)
+
+
diff --git a/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
new file mode 100644
index 0000000000..cc9b8048ca
--- /dev/null
+++ b/lib/erl_interface/test/ei_print_SUITE_data/ei_print_test.c
@@ -0,0 +1,175 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include "ei_runner.h"
+
+/*
+ * Purpose: Tests the ei_print() function.
+ * Author: Jakob
+ */
+
+static void
+send_printed3(char* format, char* p1, char* p2, int fl)
+{
+ char* b = NULL;
+ char fn[100], * tmp = getenv("temp");
+ FILE* f;
+ int n, index = 0, ver;
+ ei_x_buff x;
+
+ ei_x_new(&x);
+ if (fl) {
+ ei_x_format(&x, format, *(float*)p1, *(float*)p2);
+ } else {
+ ei_x_format(&x, format, p1, p2);
+ }
+#ifdef VXWORKS
+ tmp = ".";
+#else
+ if (tmp == NULL) tmp = "/tmp";
+#endif
+ strcpy(fn, tmp);
+ strcat(fn, "/ei_print_test.txt");
+ f = fopen(fn, "w+");
+ ei_decode_version(x.buff, &index, &ver);
+ n = ei_print_term(f, x.buff, &index);
+ fseek(f, 0, SEEK_SET);
+ b = malloc(n+1);
+ fread(b, 1, n, f);
+ b[n] = '\0';
+ fclose(f);
+ x.index = 0;
+ ei_x_format(&x, "~s", b);
+ send_bin_term(&x);
+ free(b);
+ ei_x_free(&x);
+}
+
+static void
+send_printed(char* format)
+{
+ send_printed3(format, NULL, NULL, 0);
+}
+
+static void
+send_printed2(char* format, char* p)
+{
+ send_printed3(format, p, NULL, 0);
+}
+
+static void send_printed3f(char* format, float f1, float f2)
+{
+ send_printed3(format, (char*)&f1, (char*)&f2, 1);
+}
+
+TESTCASE(atoms)
+{
+ send_printed("''");
+ send_printed("'a'");
+ send_printed("'A'");
+ send_printed("'abc'");
+ send_printed("'Abc'");
+ send_printed("'ab@c'");
+ send_printed("'The rain in Spain stays mainly in the plains'");
+
+ send_printed("a");
+ send_printed("ab");
+ send_printed("abc");
+ send_printed("ab@c");
+ send_printed(" abcdefghijklmnopq ");
+
+ send_printed2("~a", "");
+ send_printed2("~a", "a");
+ send_printed2("~a", "A");
+ send_printed2("~a", "abc");
+ send_printed2("~a", "Abc");
+ send_printed2("~a", "ab@c");
+ send_printed2("~a", "The rain in Spain stays mainly in the plains");
+
+ send_printed2("~a", "a");
+ send_printed2("~a", "ab");
+ send_printed2("~a", "abc");
+ send_printed2("~a","ab@c");
+ send_printed2("~a", " abcdefghijklmnopq ");
+
+
+ report(1);
+}
+
+TESTCASE(tuples)
+{
+ send_printed("{}");
+ send_printed("{a}");
+ send_printed("{a, b}");
+ send_printed("{a, b, c}");
+ send_printed("{1}");
+ send_printed("{[]}");
+ send_printed("{[], []}");
+ send_printed("{[], a, b, c}");
+ send_printed("{[], a, [], b, c}");
+ send_printed("{[], a, '', b, c}");
+
+ report(1);
+}
+
+
+
+TESTCASE(lists)
+{
+ ei_x_buff x;
+
+ send_printed("[]");
+ send_printed("[a]");
+ send_printed("[a, b]");
+ send_printed("[a, b, c]");
+ send_printed("[1]");
+ send_printed("[[]]");
+ send_printed("[[], []]");
+ send_printed("[[], a, b, c]");
+ send_printed("[[], a, [], b, c]");
+ send_printed("[[], a, '', b, c]");
+ send_printed("[[x, 2], [y, 3], [z, 4]]");
+
+ /* more tests needed */
+ send_printed3f("[{pi, ~f}, {'cos(70)', ~f}]",
+ (float)3.1415, (float)0.34202);
+ send_printed3f("[[pi, ~f], ['cos(70)', ~f]]",
+ (float)3.1415, (float)0.34202);
+
+ send_printed2("[~i]", (char*)-1);
+ report(1);
+}
+
+TESTCASE(strings)
+{
+ ei_x_buff x;
+
+ send_printed("\"\n\"");
+ send_printed("\"\r\n\"");
+ send_printed("\"a\"");
+ send_printed("\"A\"");
+ send_printed("\"0\"");
+ send_printed("\"9\"");
+ send_printed("\"The rain in Spain stays mainly in the plains\"");
+ send_printed("\" abcdefghijklmnopq \"");
+
+ report(1);
+}
+
+
diff --git a/lib/erl_interface/test/ei_tmo_SUITE.erl b/lib/erl_interface/test/ei_tmo_SUITE.erl
new file mode 100644
index 0000000000..0c211aa148
--- /dev/null
+++ b/lib/erl_interface/test/ei_tmo_SUITE.erl
@@ -0,0 +1,666 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(ei_tmo_SUITE).
+
+-include("test_server.hrl").
+-include_lib("kernel/include/inet.hrl").
+-include("ei_tmo_SUITE_data/ei_tmo_test_cases.hrl").
+
+-define(dummy_host,test01).
+
+-export([all/1, init_per_testcase/2, fin_per_testcase/2,
+ framework_check/1, ei_accept_tmo/1, ei_connect_tmo/1, ei_send_tmo/1,
+ ei_recv_tmo/1]).
+
+all(suite) -> [framework_check,ei_accept_tmo,ei_connect_tmo,
+ ei_send_tmo,ei_recv_tmo].
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?t:minutes(1)),
+ % test if platform is vxworks_simso
+ ?line {_,Host} = split(node()),
+ Bool = case atom_to_list(Host) of
+ [$v,$x,$s,$i,$m | _] -> true;
+ _ -> false
+ end,
+ [{vxsim,Bool},{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+framework_check(doc) ->
+ ["Check the framework."];
+framework_check(suite) ->
+ [];
+framework_check(Config) when is_list(Config) ->
+ %%dbg:tracer(),
+ %%dbg:p(self()),
+ ?line P = runner:start(?framework_check),
+ ?line runner:send_term(P,{hello,world}),
+ ?line {term, {hello,world}} = runner:get_term(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+
+ei_recv_tmo(doc) ->
+ ["Check recv with timeouts."];
+ei_recv_tmo(suite) ->
+ [];
+ei_recv_tmo(Config) when is_list(Config) ->
+ ?line do_one_recv(c_node_recv_tmo_1),
+ ?line do_one_recv_failure(c_node_recv_tmo_2),
+ ok.
+
+
+do_one_recv(CNode) ->
+ ?line {_,Host} = split(node()),
+ ?line P1 = runner:start(?recv_tmo),
+ ?line runner:send_term(P1,{CNode,
+ erlang:get_cookie(),
+ node()}),
+ ?line {term, X} = runner:get_term(P1, 10000),
+ ?line true = is_integer(X),
+ ?line CNode1 = join(CNode,Host),
+ ?line Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]},
+ ?line {test,CNode1} ! Term1,
+ ?line {term, Term1} = runner:get_term(P1, 10000),
+ ?line runner:recv_eot(P1).
+
+do_one_recv_failure(CNode) ->
+ ?line P1 = runner:start(?recv_tmo),
+ ?line runner:send_term(P1,{CNode,
+ erlang:get_cookie(),
+ node()}),
+ ?line {term, X} = runner:get_term(P1, 10000),
+ ?line true = is_integer(X),
+ ?line {term, {Ret,ETimedout,ETimedout}} = runner:get_term(P1, 10000),
+ ?line true = (Ret < 0),
+ ?line runner:recv_eot(P1).
+
+
+ei_send_tmo(doc) ->
+ ["Check send with timeouts."];
+ei_send_tmo(suite) ->
+ [];
+ei_send_tmo(Config) when is_list(Config) ->
+ %dbg:tracer(),
+ %dbg:p(self()),
+ VxSim = ?config(vxsim, Config),
+ ?line register(ei_send_tmo_1,self()),
+ ?line do_one_send(self(),c_node_send_tmo_1),
+ ?line do_one_send(ei_send_tmo_1,c_node_send_tmo_2),
+ ?line do_one_send_failure(self(),cccc1,c_nod_send_tmo_3,VxSim),
+ ?line do_one_send_failure(ei_send_tmo_1,cccc2,c_nod_send_tmo_4,VxSim),
+ ok.
+
+
+do_one_send(From,CNode) ->
+ ?line {_,Host} = split(node()),
+ ?line P1 = runner:start(?send_tmo),
+ ?line runner:send_term(P1,{CNode,
+ erlang:get_cookie(),
+ node()}),
+ ?line {term, X} = runner:get_term(P1, 10000),
+ ?line true = is_integer(X),
+ ?line CNode1 = join(CNode,Host),
+ ?line Term1 = {hej,[hopp,{i,[lingon,"skogen"]}]},
+ ?line {test,CNode1} ! {From,1,Term1},
+ ?line ok = receive
+ Term1 ->
+ ok
+ after 2000 ->
+ error
+ end,
+ ?line {term, 0} = runner:get_term(P1, 10000),
+ ?line runner:recv_eot(P1).
+
+do_one_send_failure(From,FakeName,CName,VxSim) ->
+ ?line {_,Host} = split(node()),
+ ?line OurName = join(FakeName,Host),
+ ?line Node = join(CName,Host),
+ ?line LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of
+ {ok, Socket} ->
+ ?line Socket;
+ Else ->
+ ?line exit(Else)
+ end,
+ ?line EpmdSocket = register(OurName, LSocket, 1, 5),
+ ?line P3 = runner:start(?send_tmo),
+ ?line Cookie = kaksmula_som_ingen_bryr_sig_om,
+ ?line runner:send_term(P3,{CName,
+ Cookie,
+ OurName}),
+ ?line SocketB = case gen_tcp:accept(LSocket) of
+ {ok, Socket1} ->
+ ?line Socket1;
+ Else2 ->
+ ?line exit(Else2)
+ end,
+ ?line {hidden,Node,5} = recv_name(SocketB), % See 1)
+ ?line send_status(SocketB, ok),
+ ?line MyChallengeB = gen_challenge(),
+ ?line send_challenge(SocketB, OurName, MyChallengeB, 5),
+ ?line HisChallengeB = recv_challenge_reply(
+ SocketB,
+ MyChallengeB,
+ Cookie),
+ ?line DigestB = gen_digest(HisChallengeB,Cookie),
+ ?line send_challenge_ack(SocketB, DigestB),
+ ?line inet:setopts(SocketB, [{active, false},
+ {packet, 4}]),
+ ?line {term, X} = runner:get_term(P3, 10000),
+ ?line true = is_integer(X),
+ ?line Message = [112,term_to_binary({6,self(),'',test}),
+ term_to_binary({From,10000,
+ {app,["lapp",{sa,["att",du,{slapp,
+ sitta}]}]}})],
+ ?line gen_tcp:send(SocketB,Message),
+
+ %% At this point the test program starts sending messages (max 10000). Since
+ %% we're not receiving, eventually the send buffer fills up. Then no more
+ %% sending is possible and select() times out. The number of messages sent
+ %% before this happens is returned in Iters. The timeout value for get_term/2
+ %% must be large enough so there's time for the select() to time out and
+ %% the test program to return the error tuple (below).
+ Res0 =
+ if VxSim == false ->
+ ?line {term,{Res,ETO,Iters,ETO}} = runner:get_term(P3, 20000),
+ Res;
+ true -> % relax the test for vxsim
+ ?line case runner:get_term(P3, 20000) of
+ {term,{Res,ETO,Iters,ETO}} ->
+ Res;
+ {term,{Res,_,Iters,ETO}} -> % EIO?
+ Res
+ end
+ end,
+ ?line runner:recv_eot(P3),
+ ?line true = ((Res0 < 0) and (Iters > 0)),
+ ?line gen_tcp:close(SocketB),
+ ?line gen_tcp:close(EpmdSocket),
+ ok.
+
+
+ei_connect_tmo(doc) ->
+ ["Check accept with timeouts."];
+ei_connect_tmo(suite) ->
+ [];
+ei_connect_tmo(Config) when is_list(Config) ->
+ %dbg:tracer(),
+ %dbg:p(self()),
+ VxSim = ?config(vxsim, Config),
+ DummyNode = make_and_check_dummy(),
+ ?line P = runner:start(?connect_tmo),
+ ?line runner:send_term(P,{c_nod_connect_tmo_1,
+ kaksmula_som_ingen_bryr_sig_om,
+ DummyNode}),
+ ETimedout =
+ if VxSim == false ->
+ ?line {term,{-3,ETO,ETO}} = runner:get_term(P, 10000),
+ ?line ETO;
+ true -> % relax the test for vxsim
+ ?line case runner:get_term(P, 10000) of
+ {term,{-3,ETO,ETO}} ->
+ ?line ETO;
+ {term,{-1,_,ETO}} -> % EHOSTUNREACH = ok
+ ?line ETO
+ end
+ end,
+ ?line runner:recv_eot(P),
+ ?line P2 = runner:start(?connect_tmo),
+ ?line runner:send_term(P2,{c_nod_connect_tmo_2,
+ erlang:get_cookie(),
+ node()}),
+ ?line {term, X} = runner:get_term(P2, 10000),
+ ?line runner:recv_eot(P2),
+ ?line true = is_integer(X),
+ %% Aborted handshake test...
+ ?line {_,Host} = split(node()),
+ ?line OurName = join(cccc,Host),
+ ?line Node = join(c_nod_connect_tmo_3,Host),
+ ?line LSocket = case gen_tcp:listen(0, [{active, false}, {packet,2}]) of
+ {ok, Socket} ->
+ ?line Socket;
+ Else ->
+ ?line exit(Else)
+ end,
+ ?line EpmdSocket = register(OurName, LSocket, 1, 5),
+ ?line P3 = runner:start(?connect_tmo),
+ ?line Cookie = kaksmula_som_ingen_bryr_sig_om,
+ ?line runner:send_term(P3,{c_nod_connect_tmo_3,
+ Cookie,
+ OurName}),
+ ?line SocketB = case gen_tcp:accept(LSocket) of
+ {ok, Socket1} ->
+ ?line Socket1;
+ Else2 ->
+ ?line exit(Else2)
+ end,
+ ?line {hidden,Node,5} = recv_name(SocketB), % See 1)
+ ?line send_status(SocketB, ok),
+ ?line MyChallengeB = gen_challenge(),
+ ?line send_challenge(SocketB, OurName, MyChallengeB, 5),
+ ?line HisChallengeB = recv_challenge_reply(
+ SocketB,
+ MyChallengeB,
+ Cookie),
+ ?line {term,{-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000),
+ ?line runner:recv_eot(P3),
+ ?line gen_tcp:close(SocketB),
+ ?line gen_tcp:close(EpmdSocket),
+ ok.
+
+
+ei_accept_tmo(doc) ->
+ ["Check accept with timeouts."];
+ei_accept_tmo(suite) ->
+ [];
+ei_accept_tmo(Config) when is_list(Config) ->
+ %%dbg:tracer(),
+ %%dbg:p(self()),
+ ?line P = runner:start(?accept_tmo),
+ ?line runner:send_term(P,{c_nod_som_ingen_kontaktar_1,
+ kaksmula_som_ingen_bryr_sig_om}),
+ ?line {term,{-1,ETimedout,ETimedout}} = runner:get_term(P, 10000),
+ ?line runner:recv_eot(P),
+ ?line P2 = runner:start(?accept_tmo),
+ ?line runner:send_term(P2,{c_nod_som_vi_kontaktar_1,
+ erlang:get_cookie()}),
+ ?line receive after 1000 -> ok end,
+ ?line CNode1 = make_node(c_nod_som_vi_kontaktar_1),
+ ?line {ignored,CNode1} ! tjenare,
+ ?line {term, X} = runner:get_term(P2, 10000),
+ ?line runner:recv_eot(P2),
+ ?line true = is_integer(X),
+ ?line P3 = runner:start(?accept_tmo),
+ ?line runner:send_term(P3,{c_nod_som_vi_kontaktar_2,
+ erlang:get_cookie()}),
+ ?line receive after 1000 -> ok end,
+ ?line CNode2 = make_node(c_nod_som_vi_kontaktar_2),
+ ?line {NA,NB} = split(CNode2),
+ ?line {_,Host} = split(node()),
+ ?line OurName = join(ccc,Host),
+ ?line {port,PortNo,_} = erl_epmd:port_please(NA,NB),
+ ?line {ok, SocketA} = gen_tcp:connect(atom_to_list(NB),PortNo,
+ [{active,false},
+ {packet,2}]),
+ ?line send_name(SocketA,OurName,5),
+ ?line ok = recv_status(SocketA),
+ ?line {hidden,Node,5,HisChallengeA} = recv_challenge(SocketA), % See 1)
+ ?line OurChallengeA = gen_challenge(),
+ ?line OurDigestA = gen_digest(HisChallengeA, erlang:get_cookie()),
+ %% Dont do the last two steps of the connection setup...
+ %% send_challenge_reply(SocketA, OurChallengeA, OurDigestA),
+ %% ok = recv_challenge_ack(SocketA, OurChallengeA, erlang:get_cookie()),
+ ?line {term, {-1,ETimedout,ETimedout}} = runner:get_term(P3, 10000),
+ ?line runner:recv_eot(P3),
+ ?line gen_tcp:close(SocketA),
+ ok.
+
+make_node(X) ->
+ list_to_atom(atom_to_list(X) ++ "@" ++
+ hd(tl(string:tokens(atom_to_list(node()),"@")))).
+
+
+make_and_check_dummy() ->
+ % First check that the host has an ip and is *not* reachable
+ ?line case gen_tcp:connect(?dummy_host,23,[{active,false}],5000) of
+ {error,timeout} -> ok;
+ {error,ehostunreach} -> ok
+ end,
+
+ list_to_atom("dummy@"++atom_to_list(?dummy_host)).
+
+%%
+%% Stolen from the erl_distribution_wb_test in kernel
+%% To be able to do partial handshakes...
+%%
+
+-define(to_port(Socket, Data),
+ case inet_tcp:send(Socket, Data) of
+ {error, closed} ->
+ self() ! {tcp_closed, Socket},
+ {error, closed};
+ R ->
+ R
+ end).
+
+-define(DFLAG_PUBLISHED,1).
+-define(DFLAG_ATOM_CACHE,2).
+-define(DFLAG_EXTENDED_REFERENCES,4).
+-define(DFLAG_EXTENDED_PIDS_PORTS,16#100).
+-define(DFLAG_DIST_MONITOR,8).
+
+%% From R9 and forward extended references is compulsory
+-define(COMPULSORY_DFLAGS, (?DFLAG_EXTENDED_REFERENCES bor ?DFLAG_EXTENDED_PIDS_PORTS)).
+
+-define(shutdown(X), exit(X)).
+-define(int16(X), [((X) bsr 8) band 16#ff, (X) band 16#ff]).
+
+-define(int32(X),
+ [((X) bsr 24) band 16#ff, ((X) bsr 16) band 16#ff,
+ ((X) bsr 8) band 16#ff, (X) band 16#ff]).
+
+-define(i16(X1,X0),
+ (?u16(X1,X0) -
+ (if (X1) > 127 -> 16#10000; true -> 0 end))).
+
+-define(u16(X1,X0),
+ (((X1) bsl 8) bor (X0))).
+
+-define(u32(X3,X2,X1,X0),
+ (((X3) bsl 24) bor ((X2) bsl 16) bor ((X1) bsl 8) bor (X0))).
+
+%%
+%% Handshake utilities
+%%
+
+%%
+%% MD5 hashing
+%%
+
+%% This is no proper random number, but that is not really important in
+%% this test
+gen_challenge() ->
+ {_,_,N} = erlang:now(),
+ N.
+
+%% Generate a message digest from Challenge number and Cookie
+gen_digest(Challenge, Cookie) when is_integer(Challenge), is_atom(Cookie) ->
+ C0 = erlang:md5_init(),
+ C1 = erlang:md5_update(C0, atom_to_list(Cookie)),
+ C2 = erlang:md5_update(C1, integer_to_list(Challenge)),
+ binary_to_list(erlang:md5_final(C2)).
+
+
+%%
+%% The differrent stages of the MD5 handshake
+%%
+
+send_status(Socket, Stat) ->
+ case gen_tcp:send(Socket, [$s | atom_to_list(Stat)]) of
+ {error, _} ->
+ ?shutdown(could_not_send_status);
+ _ ->
+ true
+ end.
+
+
+recv_status(Socket) ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok, [$s|StrStat]} ->
+ list_to_atom(StrStat);
+ Bad ->
+ exit(Bad)
+ end.
+
+send_challenge(Socket, Node, Challenge, Version) ->
+ send_challenge(Socket, Node, Challenge, Version, ?COMPULSORY_DFLAGS).
+send_challenge(Socket, Node, Challenge, Version, Flags) ->
+ {ok, {{Ip1,Ip2,Ip3,Ip4}, _}} = inet:sockname(Socket),
+ ?to_port(Socket, [$n,?int16(Version),?int32(Flags),
+ ?int32(Challenge), atom_to_list(Node)]).
+
+recv_challenge(Socket) ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} ->
+ Flags = ?u32(Fl1,Fl2,Fl3,Fl4),
+ Type = case Flags band ?DFLAG_PUBLISHED of
+ 0 ->
+ hidden;
+ _ ->
+ normal
+ end,
+ Node =list_to_atom(Ns),
+ Version = ?u16(V1,V0),
+ Challenge = ?u32(CA3,CA2,CA1,CA0),
+ {Type,Node,Version,Challenge};
+ _ ->
+ ?shutdown(no_node)
+ end.
+
+send_challenge_reply(Socket, Challenge, Digest) ->
+ ?to_port(Socket, [$r,?int32(Challenge),Digest]).
+
+recv_challenge_reply(Socket, ChallengeA, Cookie) ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok,[$r,CB3,CB2,CB1,CB0 | SumB]} when length(SumB) == 16 ->
+ SumA = gen_digest(ChallengeA, Cookie),
+ ChallengeB = ?u32(CB3,CB2,CB1,CB0),
+ if SumB == SumA ->
+ ChallengeB;
+ true ->
+ ?shutdown(bad_challenge_reply)
+ end;
+ _ ->
+ ?shutdown(no_node)
+ end.
+
+send_challenge_ack(Socket, Digest) ->
+ ?to_port(Socket, [$a,Digest]).
+
+recv_challenge_ack(Socket, ChallengeB, CookieA) ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok,[$a | SumB]} when length(SumB) == 16 ->
+ SumA = gen_digest(ChallengeB, CookieA),
+ if SumB == SumA ->
+ ok;
+ true ->
+ ?shutdown(bad_challenge_ack)
+ end;
+ _ ->
+ ?shutdown(bad_challenge_ack)
+ end.
+
+send_name(Socket, MyNode0, Version) ->
+ send_name(Socket, MyNode0, Version, ?COMPULSORY_DFLAGS).
+send_name(Socket, MyNode0, Version, Flags) ->
+ MyNode = atom_to_list(MyNode0),
+ ?to_port(Socket, [$n,?int16(Version),?int32(Flags)] ++
+ MyNode).
+
+%%
+%% recv_name is common for both old and new handshake.
+%%
+recv_name(Socket) ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok,Data} ->
+ get_name(Data);
+ Res ->
+ ?shutdown({no_node,Res})
+ end.
+
+get_name([$m,VersionA,VersionB,_Ip1,_Ip2,_Ip3,_Ip4|OtherNode]) ->
+ {normal, list_to_atom(OtherNode), ?u16(VersionA,VersionB)};
+get_name([$h,VersionA,VersionB,_Ip1,_Ip2,_Ip3,_Ip4|OtherNode]) ->
+ {hidden, list_to_atom(OtherNode), ?u16(VersionA,VersionB)};
+get_name([$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode]) ->
+ Type = case ?u32(Flag1, Flag2, Flag3, Flag4) band ?DFLAG_PUBLISHED of
+ 0 ->
+ hidden;
+ _ ->
+ normal
+ end,
+ {Type, list_to_atom(OtherNode),
+ ?u16(VersionA,VersionB)};
+get_name(Data) ->
+ ?shutdown(Data).
+
+%%
+%% tell_name is for old handshake
+%%
+tell_name(Socket, MyNode0, Version) ->
+ MyNode = atom_to_list(MyNode0),
+ {ok, {{Ip1,Ip2,Ip3,Ip4}, _}} = inet:sockname(Socket),
+ ?to_port(Socket, [$h,?int16(Version),Ip1,Ip2,Ip3,Ip4] ++
+ MyNode).
+
+%%
+%% The communication with EPMD follows
+%%
+do_register_node(NodeName, TcpPort, VLow, VHigh) ->
+ case gen_tcp:connect({127,0,0,1}, get_epmd_port(), []) of
+ {ok, Socket} ->
+ {N0,_} = split(NodeName),
+ Name = atom_to_list(N0),
+ Extra = "",
+ Elen = length(Extra),
+ Len = 1+2+1+1+2+2+2+length(Name)+2+Elen,
+ gen_tcp:send(Socket, [?int16(Len), $x,
+ ?int16(TcpPort),
+ $M,
+ 0,
+ ?int16(VHigh),
+ ?int16(VLow),
+ ?int16(length(Name)),
+ Name,
+ ?int16(Elen),
+ Extra]),
+ case wait_for_reg_reply(Socket, []) of
+ {error, epmd_close} ->
+ exit(epmd_broken);
+ Other ->
+ Other
+ end;
+ Error ->
+ Error
+ end.
+
+wait_for_reg_reply(Socket, SoFar) ->
+ receive
+ {tcp, Socket, Data0} ->
+ case SoFar ++ Data0 of
+ [$y, Result, A, B] ->
+ case Result of
+ 0 ->
+ {alive, Socket, ?u16(A, B)};
+ _ ->
+ {error, duplicate_name}
+ end;
+ Data when length(Data) < 4 ->
+ wait_for_reg_reply(Socket, Data);
+ Garbage ->
+ {error, {garbage_from_epmd, Garbage}}
+ end;
+ {tcp_closed, Socket} ->
+ {error, epmd_close}
+ after 10000 ->
+ gen_tcp:close(Socket),
+ {error, no_reg_reply_from_epmd}
+ end.
+
+
+register(NodeName, ListenSocket, VLow, VHigh) ->
+ {ok,{_,TcpPort}} = inet:sockname(ListenSocket),
+ case do_register_node(NodeName, TcpPort, VLow, VHigh) of
+ {alive, Socket, Creation} ->
+ Socket;
+ Other ->
+ exit(Other)
+ end.
+
+
+%%
+%% Utilities
+%%
+
+%% Split a nodename
+split([$@|T],A) ->
+ {lists:reverse(A),T};
+split([H|T],A) ->
+ split(T,[H|A]).
+
+split(Atom) ->
+ {A,B} = split(atom_to_list(Atom),[]),
+ {list_to_atom(A),list_to_atom(B)}.
+
+%% Build a simple distribution message
+build_message(Cookie) ->
+ [$?,term_to_binary({6,self(),Cookie,rex}),term_to_binary(plupp)].
+
+%% Build a distribution message that will make rex answer
+build_rex_message(Cookie,OurName) ->
+ [$?,term_to_binary({6,self(),Cookie,rex}),
+ term_to_binary({'$gen_cast',
+ {cast,
+ rpc,
+ cast,
+ [OurName, hello, world, []],
+ self()} })].
+
+%% Receive a distribution message
+recv_message(Socket) ->
+ case gen_tcp:recv(Socket, 0) of
+ {ok,Data} ->
+ B0 = list_to_binary(Data),
+ {_,B1} = erlang:split_binary(B0,1),
+ Header = erlang:binary_to_term(B1),
+ Siz = size(term_to_binary(Header)),
+ {_,B2} = erlang:split_binary(B1,Siz),
+ Message = case (catch erlang:binary_to_term(B2)) of
+ {'EXIT', _} ->
+ could_not_digest_message;
+ Other ->
+ Other
+ end,
+ {Header, Message};
+ Res ->
+ exit({no_message,Res})
+ end.
+
+%% Build a nodename
+join(Name,Host) ->
+ list_to_atom(atom_to_list(Name) ++ "@" ++ atom_to_list(Host)).
+
+%% start/stop slave.
+start_node(Name, Param) ->
+ ?t:start_node(Name, slave, [{args, Param}]).
+
+stop_node(Node) ->
+ ?t:stop_node(Node).
+
+
+get_nodenames(N, T) ->
+ get_nodenames(N, T, []).
+
+get_nodenames(0, _, Acc) ->
+ Acc;
+get_nodenames(N, T, Acc) ->
+ {A, B, C} = now(),
+ get_nodenames(N-1, T, [list_to_atom(atom_to_list(?MODULE)
+ ++ "-"
+ ++ atom_to_list(T)
+ ++ "-"
+ ++ integer_to_list(A)
+ ++ "-"
+ ++ integer_to_list(B)
+ ++ "-"
+ ++ integer_to_list(C)) | Acc]).
+
+get_epmd_port() ->
+ case init:get_argument(epmd_port) of
+ {ok, [[PortStr|_]|_]} when is_list(PortStr) ->
+ list_to_integer(PortStr);
+ error ->
+ 4369 % Default epmd port
+ end.
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..6eb9f2ce71
--- /dev/null
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ei_tmo_test_decl.c: ei_tmo_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ei_tmo_test -s erlang halt
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..a49eeccc02
--- /dev/null
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/Makefile.src
@@ -0,0 +1,41 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/ei_runner@obj@ \
+ $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EI_TMO_OBJS = ei_tmo_test@obj@ ei_tmo_test_decl@obj@
+
+all: ei_tmo_test@exe@
+
+clean:
+ $(RM) $(EI_TMO_OBJS)
+ $(RM) ei_tmo_test@exe@
+
+ei_tmo_test@exe@: $(EI_TMO_OBJS) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EI_TMO_OBJS) $(LIBFLAGS)
+
diff --git a/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
new file mode 100644
index 0000000000..2cc9af975d
--- /dev/null
+++ b/lib/erl_interface/test/ei_tmo_SUITE_data/ei_tmo_test.c
@@ -0,0 +1,767 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2003-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include <stdio.h>
+#include <string.h>
+#ifdef VXWORKS
+#include "reclaim.h"
+#endif
+
+#ifdef __WIN32__
+#include <winsock2.h>
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+#include "ei_runner.h"
+
+#ifndef __WIN32__
+#define closesocket(X) close(X)
+#endif
+
+#define DEBUG 1
+
+#ifdef DEBUG
+#include <stdarg.h>
+
+FILE *debugfile = NULL;
+#define OPEN_DEBUGFILE(Number) debugf_open(Number)
+#define CLOSE_DEBUGFILE() debugf_close()
+#define DEBUGF(X) debugf X
+
+static void debugf(char *format, ...)
+{
+ va_list ap;
+ va_start(ap,format);
+ if (debugfile) {
+ vfprintf(debugfile,format,ap);
+ fflush(debugfile);
+ } else {
+ fprintf(stderr,"Attempt to write to debugfile when not open...\n");
+ }
+ va_end(ap);
+}
+
+static void debugf_open(int number)
+{
+ char filename[1024];
+ sprintf(filename,"ei_tmo_test%d.debug",number);
+#if !defined(VXWORKS) && !defined(__WIN32__) && !defined(_OSE_)
+ close(2);
+#endif
+ debugfile = fopen(filename,"a");
+ fprintf(debugfile,"===================================================\n");
+}
+
+static void debugf_close(void)
+{
+ if (debugfile)
+ fclose(debugfile);
+}
+
+#else
+#define OPEN_DEBUGFILE(X) /* noop */
+#define CLOSE_DEBUGFILE() /* noop */
+#define DEBUGF(X) /* noop */
+#endif
+
+TESTCASE(framework_check)
+{
+ char *ptr = NULL;
+ int len;
+
+#ifdef DEBUG
+ int version;
+ int i;
+#endif
+
+ OPEN_DEBUGFILE(1);
+
+ DEBUGF(("B�rjar... \n"));
+ ptr = read_packet(&len);
+ if (*ptr != 't') {
+ DEBUGF(("Gick fel \n"));
+ report(1);
+ } else {
+ ei_x_buff x;
+ ei_x_new(&x);
+ ei_x_append_buf(&x, ptr+1,len-1);
+ DEBUGF(("Gick bra? %d\n",x.index));
+#ifdef DEBUG
+ for(i=0;i < x.index; ++i)
+ DEBUGF(("%d ",(int) ((unsigned char *) x.buff)[i]));
+ DEBUGF(("\n"));
+ len = 0;
+ ei_decode_version(x.buff,&len,&version);
+ ei_print_term(debugfile,x.buff,&len);
+ fflush(debugfile);
+#endif
+ send_bin_term(&x);
+ ei_x_free(&x);
+ }
+ if (ptr != NULL)
+ free(ptr);
+ CLOSE_DEBUGFILE();
+ report(1);
+}
+
+int decode_request(char **nodename_p, char **cookie_p, char **peername_p)
+{
+ char *nodename = NULL;
+ char *cookie = NULL;
+ char *peername = NULL;
+ char *ptr = NULL;
+ ei_x_buff x;
+ int len;
+ int version;
+ int type;
+ int size;
+ int expected_size = (peername_p == NULL) ? 2 : 3;
+ int ret = -1;
+
+ ptr = read_packet(&len);
+ ei_x_new(&x);
+ if (*ptr != 't') {
+ goto cleanup;
+ }
+ ei_x_append_buf(&x, ptr+1,len-1);
+ len = 0;
+ ei_decode_version(x.buff,&len,&version);
+#ifdef DEBUG
+ {
+ int tlen = len;
+ ei_print_term(debugfile,x.buff,&tlen);
+ DEBUGF(("\n"));
+ }
+#endif
+ if (ei_get_type(x.buff,&len,&type,&size) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (type != ERL_SMALL_TUPLE_EXT || size != expected_size) {
+ DEBUGF(("Failure at line %d, type=%d, size = %d\n",__LINE__,
+ type,size));
+ goto cleanup;
+ }
+ if (ei_decode_tuple_header(x.buff,&len,&size) != 0 || size != expected_size) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (ei_get_type(x.buff,&len,&type,&size) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (type != ERL_ATOM_EXT) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ nodename = malloc(size+1);
+ ei_decode_atom(x.buff,&len,nodename);
+ nodename[size] = '\0'; /* needed????? */
+ if (ei_get_type(x.buff,&len,&type,&size) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (type != ERL_ATOM_EXT) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ cookie = malloc(size + 1);
+ ei_decode_atom(x.buff,&len,cookie);
+ cookie[size] = '\0'; /* needed????? */
+ if (expected_size > 2) {
+ if (ei_get_type(x.buff,&len,&type,&size) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (type != ERL_ATOM_EXT) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ peername = malloc(size + 1);
+ ei_decode_atom(x.buff,&len,peername);
+ peername[size] = '\0'; /* needed????? */
+ DEBUGF(("nodename = %s, cookie = %s, peername = %s\n",
+ nodename, cookie, peername));
+ *peername_p = peername;
+ peername = NULL;
+ } else {
+ DEBUGF(("nodename = %s, cookie = %s\n",
+ nodename, cookie));
+ }
+ *nodename_p = nodename;
+ nodename = NULL;
+ *cookie_p = cookie;
+ cookie = NULL;
+ ret = 0;
+ cleanup:
+ ei_x_free(&x);
+ if (ptr != NULL) {
+ free(ptr);
+ }
+ if (nodename != NULL) {
+ free(nodename);
+ }
+ if (cookie != NULL) {
+ free(cookie);
+ }
+ if (peername != NULL) {
+ free(peername);
+ }
+ return ret;
+}
+
+int get_message(int com_sock, ei_x_buff *buff,
+ char *atom_buff, erlang_pid *pid, int *iterations)
+{
+ ei_x_buff buffer;
+ int ret_val,index;
+ erlang_msg msg;
+ int res = -1;
+ int totlen;
+ int type;
+ int size;
+ int version;
+ long tmp;
+
+ ei_x_new(&buffer);
+
+ for (;;) {
+ /* Reset buffer index before reading */
+ buffer.index = 0;
+ /* Receive message */
+ if ((ret_val = ei_xreceive_msg(com_sock, &msg, &buffer)) ==
+ ERL_TICK) {
+ /* Ticks are automatically answered, just continue */
+ continue;
+ } else if (ret_val != ERL_MSG) {
+ DEBUGF(("Peer has closed, ret_val = %d (%d).\n",
+ ret_val,erl_errno));
+ goto cleanup;
+ }
+ switch (msg.msgtype) {
+ case ERL_SEND:
+ case ERL_REG_SEND:
+ index = 0;
+ ei_decode_version(buffer.buff,&index,&version);
+ DEBUGF(("Peer sent the following message to me: "));
+#ifdef DEBUG
+ {
+ int ndx = index;
+ /*in debug log on Unix*/
+ ei_print_term(debugfile, buffer.buff, &ndx);
+ }
+#endif
+ DEBUGF(("\n"));
+ if (ei_get_type(buffer.buff,&index,&type,&size) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (type != ERL_SMALL_TUPLE_EXT || size != 3) {
+ DEBUGF(("Failure at line %d, type=%d, size = %d\n",__LINE__,
+ type,size));
+ goto cleanup;
+ }
+ if (ei_decode_tuple_header(buffer.buff,&index,&size) != 0 ||
+ size != 3) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (ei_get_type(buffer.buff,&index,&type,&size) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (type == ERL_ATOM_EXT) {
+ ei_decode_atom(buffer.buff,&index,atom_buff);
+ atom_buff[size] ='\0';
+ res = 2;
+ } else if (type == ERL_PID_EXT) {
+ ei_decode_pid(buffer.buff,&index,pid);
+ res = 1;
+ } else {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (ei_get_type(buffer.buff,&index,&type,&size) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ switch (type) {
+ case ERL_SMALL_INTEGER_EXT:
+ case ERL_INTEGER_EXT:
+ ei_decode_long(buffer.buff,&index,&tmp);
+ break;
+ default:
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+
+ *iterations = (int)tmp;
+
+ totlen = buffer.index - index;
+ ei_x_append_buf(buff,buffer.buff+index,totlen);
+ goto cleanup;
+ default:
+ DEBUGF(("Unexpected message type from peer. Goodbye.\n"));
+ goto cleanup;
+ }
+ }
+
+ cleanup:
+ ei_x_free(&buffer);
+ return res;
+}
+TESTCASE(recv_tmo)
+{
+ char *nodename = NULL;
+ char *cookie = NULL;
+ char *peername = NULL;
+ int com_sock = -1;
+ ei_cnode nodeinfo;
+
+
+ OPEN_DEBUGFILE(5);
+
+ if (decode_request(&nodename,&cookie,&peername) != 0) {
+ goto cleanup;
+ }
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+
+ if ((com_sock = ei_connect_tmo(&nodeinfo, peername, 5000)) < 0) {
+ ei_x_buff answer;
+ DEBUGF(("Got error while connecting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+ ei_x_format(&answer,"{~i,~i,~i}",com_sock,erl_errno,ETIMEDOUT);
+#ifdef DEBUG
+ {
+ int tlen = 0;
+ int v;
+ ei_decode_version(answer.buff,&tlen,&v);
+ ei_print_term(debugfile,answer.buff,&tlen);
+ DEBUGF(("\n"));
+ }
+#endif
+ send_bin_term(&answer);
+ DEBUGF(("Binary term sent.\n"));
+ ei_x_free(&answer);
+ } else {
+ ei_x_buff answer;
+ int ret_val;
+ ei_x_buff buffer;
+ erlang_msg msg;
+ int index,version;
+
+ DEBUGF(("Success when connecting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+ ei_x_format(&answer,"~i",com_sock);
+ send_bin_term(&answer);
+ ei_x_free(&answer);
+ ei_x_new(&buffer);
+
+ for (;;) {
+ /* Reset buffer index before reading */
+ buffer.index = 0;
+ /* Receive message */
+ if ((ret_val = ei_xreceive_msg_tmo(com_sock, &msg, &buffer,5000))
+ == ERL_TICK) {
+ /* Ticks are automatically answered, just continue */
+ continue;
+ } else if (ret_val != ERL_MSG) {
+ ei_x_new(&answer);
+ ei_x_format(&answer,"{~i,~i,~i}",ret_val,erl_errno,ETIMEDOUT);
+ send_bin_term(&answer);
+ ei_x_free(&answer);
+ ei_x_free(&buffer);
+ DEBUGF(("Got error receiving, sending {%d,%d} and exiting\n",
+ ret_val,erl_errno));
+ goto cleanup;
+ }
+ switch (msg.msgtype) {
+ case ERL_SEND:
+ case ERL_REG_SEND:
+ index = 0;
+ ei_decode_version(buffer.buff,&index,&version);
+ DEBUGF(("Peer sent the following message to me: "));
+#ifdef DEBUG
+ {
+ int ndx = index;
+ /*in debug log on Unix*/
+ ei_print_term(debugfile, buffer.buff, &ndx);
+ }
+#endif
+ DEBUGF(("\n"));
+ send_bin_term(&buffer);
+ ei_x_free(&buffer);
+ goto cleanup;
+ default:
+ DEBUGF(("Unexpected message type from peer. Goodbye.\n"));
+ goto cleanup;
+
+ }
+ }
+ }
+cleanup:
+ if (com_sock >= 0) {
+ closesocket(com_sock);
+ }
+
+ if (nodename != NULL) {
+ free(nodename);
+ }
+ if (cookie != NULL) {
+ free(cookie);
+ }
+ if (peername != NULL) {
+ free(peername);
+ }
+ CLOSE_DEBUGFILE();
+ report(1);
+}
+
+TESTCASE(send_tmo)
+{
+ char *nodename = NULL;
+ char *cookie = NULL;
+ char *peername = NULL;
+ int com_sock = -1;
+ ei_cnode nodeinfo;
+
+
+ OPEN_DEBUGFILE(4);
+
+ if (decode_request(&nodename,&cookie,&peername) != 0) {
+ goto cleanup;
+ }
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+
+ if ((com_sock = ei_connect_tmo(&nodeinfo, peername, 5000)) < 0) {
+ ei_x_buff answer;
+ DEBUGF(("Got error while connecting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+ ei_x_format(&answer,"{~i,~i,~i}",com_sock,erl_errno,ETIMEDOUT);
+#ifdef DEBUG
+ {
+ int tlen = 0;
+ int v;
+ ei_decode_version(answer.buff,&tlen,&v);
+ ei_print_term(debugfile,answer.buff,&tlen);
+ DEBUGF(("\n"));
+ }
+#endif
+ send_bin_term(&answer);
+ DEBUGF(("Binary term sent.\n"));
+ ei_x_free(&answer);
+ } else {
+ ei_x_buff answer;
+ char atom[256];
+ erlang_pid pid;
+ int res, iterations, i;
+ ei_x_buff send_buffer;
+
+ DEBUGF(("Success when connecting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+ ei_x_format(&answer,"~i",com_sock);
+ send_bin_term(&answer);
+ ei_x_free(&answer);
+ ei_x_new_with_version(&send_buffer);
+ if ((res = get_message(com_sock, &send_buffer,
+ atom ,&pid, &iterations)) < 0) {
+ DEBUGF(("Get_message_failure at line %d\n",__LINE__));
+ ei_x_free(&send_buffer);
+ goto cleanup;
+ }
+ DEBUGF(("Get_message success (%d), bindata:\n",res));
+#ifdef DEBUG
+ {
+ int ndx = 0;
+ int v;
+ ei_decode_version(send_buffer.buff,&ndx,&v);
+ ei_print_term(debugfile, send_buffer.buff, &ndx);
+ }
+#endif
+ DEBUGF(("\n"));
+ switch (res) {
+ case 1: /* Send to pid in 'pid' */
+ ei_x_new(&answer);
+ for (i=0;i < iterations; ++i) {
+ res = ei_send_tmo(com_sock, &pid, send_buffer.buff,
+ send_buffer.index, 5000);
+ DEBUGF(("Sent bindata (%d):\n",res));
+#ifdef DEBUG
+ {
+ int ndx = 0;
+ int v;
+ ei_decode_version(send_buffer.buff,&ndx,&v);
+ ei_print_term(debugfile, send_buffer.buff, &ndx);
+ }
+#endif
+ DEBUGF(("\n"));
+ if (res < 0)
+ break;
+ }
+ if (res < 0) {
+ DEBUGF(("ei_send_tmo failure at line %d\n",__LINE__));
+ ei_x_format(&answer,"{~i,~i,~i,~i}",res,erl_errno,i,ETIMEDOUT);
+ } else {
+ ei_x_format(&answer,"~i",res);
+ }
+ send_bin_term(&answer);
+ ei_x_free(&answer);
+ ei_x_free(&send_buffer);
+ goto cleanup;
+ case 2: /* Registered name in 'atom' */
+ ei_x_new(&answer);
+ for (i=0;i < iterations; ++i) {
+ res = ei_reg_send_tmo(&nodeinfo, com_sock, atom,
+ send_buffer.buff,
+ send_buffer.index,5000);
+ if (res < 0)
+ break;
+ }
+ if (res < 0) {
+ DEBUGF(("ei_reg_send_tmo failure at line %d\n",__LINE__));
+ ei_x_format(&answer,"{~i,~i,~i,~i}",res,erl_errno,i,ETIMEDOUT);
+ } else {
+ ei_x_format(&answer,"~i",res);
+ }
+ send_bin_term(&answer);
+ ei_x_free(&answer);
+ ei_x_free(&send_buffer);
+ goto cleanup;
+ default:
+ DEBUGF(("unexpected request number %d at line %d\n",res,__LINE__));
+ ei_x_free(&send_buffer);
+ goto cleanup;
+ }
+ }
+cleanup:
+ if (com_sock >= 0) {
+ closesocket(com_sock);
+ }
+
+ if (nodename != NULL) {
+ free(nodename);
+ }
+ if (cookie != NULL) {
+ free(cookie);
+ }
+ if (peername != NULL) {
+ free(peername);
+ }
+ CLOSE_DEBUGFILE();
+ report(1);
+}
+
+
+TESTCASE(connect_tmo)
+{
+ char *nodename = NULL;
+ char *cookie = NULL;
+ char *peername = NULL;
+ int com_sock = -1;
+ ei_cnode nodeinfo;
+
+
+
+ OPEN_DEBUGFILE(3);
+
+ if (decode_request(&nodename,&cookie,&peername) != 0) {
+ goto cleanup;
+ }
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+
+ if ((com_sock = ei_connect_tmo(&nodeinfo, peername, 5000)) < 0) {
+ ei_x_buff answer;
+ DEBUGF(("Got error while connecting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+
+ /* On some systems errno gets set to EHOSTUNREACH rather than
+ ETIMEDOUT, which is ok. Let's check for that and report timeout
+ if it happens.
+ Max OS X seems to respond EHOSTDOWN, which should be ok.
+ */
+
+
+#if defined(EHOSTUNREACH)
+ if (errno == EHOSTUNREACH)
+ ei_x_format(&answer,"{~i,~i,~i}",com_sock,ETIMEDOUT,ETIMEDOUT);
+ else
+#endif
+
+#if defined(EHOSTDOWN)
+ if (errno == EHOSTDOWN)
+ ei_x_format(&answer,"{~i,~i,~i}",com_sock,ETIMEDOUT,ETIMEDOUT);
+ else
+#endif
+
+ ei_x_format(&answer,"{~i,~i,~i}",com_sock,erl_errno,ETIMEDOUT);
+
+#ifdef DEBUG
+ {
+ int tlen = 0;
+ int v;
+ ei_decode_version(answer.buff,&tlen,&v);
+ ei_print_term(debugfile,answer.buff,&tlen);
+ DEBUGF(("\n"));
+ }
+#endif
+ send_bin_term(&answer);
+ DEBUGF(("Binary term sent.\n"));
+ ei_x_free(&answer);
+ } else {
+ ei_x_buff answer;
+ DEBUGF(("Success when connecting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+ ei_x_format(&answer,"~i",com_sock);
+ send_bin_term(&answer);
+ ei_x_free(&answer);
+ }
+
+cleanup:
+ if (com_sock >= 0) {
+ closesocket(com_sock);
+ }
+
+ if (nodename != NULL) {
+ free(nodename);
+ }
+ if (cookie != NULL) {
+ free(cookie);
+ }
+ if (peername != NULL) {
+ free(peername);
+ }
+ CLOSE_DEBUGFILE();
+ report(1);
+}
+
+TESTCASE(accept_tmo)
+{
+ char *nodename = NULL;
+ char *cookie = NULL;
+ int listen_sock = -1;
+ int epmd_sock = -1;
+ int com_sock = -1;
+ struct sockaddr_in sin;
+ int sin_siz = sizeof(sin);
+ ErlConnect peer;
+ ei_cnode nodeinfo;
+
+
+
+ OPEN_DEBUGFILE(2);
+
+ putenv("EI_TRACELEVEL=10");
+
+ if (decode_request(&nodename,&cookie,NULL) != 0) {
+ goto cleanup;
+ }
+ if (ei_connect_init(&nodeinfo, nodename, cookie, 0) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+
+ if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = INADDR_ANY;
+
+ if (bind(listen_sock,(struct sockaddr *) &sin, sizeof(sin)) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (getsockname(listen_sock,
+ (struct sockaddr *) &sin, &sin_siz) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+ if (listen(listen_sock, 5) != 0) {
+ DEBUGF(("Failure at line %d\n",__LINE__));
+ goto cleanup;
+ }
+
+ if ((epmd_sock = ei_publish(&nodeinfo, ntohs(sin.sin_port))) < 0) {
+ DEBUGF(("Failure at line %d[%d,%d]\n",__LINE__,sin.sin_port,erl_errno));
+ goto cleanup;
+ }
+
+ if ((com_sock = ei_accept_tmo(&nodeinfo,
+ listen_sock, &peer, 5000)) == ERL_ERROR) {
+ ei_x_buff answer;
+ DEBUGF(("Got error while accepting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+ ei_x_format(&answer,"{~i,~i,~i}",com_sock,erl_errno,ETIMEDOUT);
+#ifdef DEBUG
+ {
+ int tlen = 0;
+ int v;
+ ei_decode_version(answer.buff,&tlen,&v);
+ ei_print_term(debugfile,answer.buff,&tlen);
+ DEBUGF(("\n"));
+ }
+#endif
+ send_bin_term(&answer);
+ DEBUGF(("Binary term sent.\n"));
+ ei_x_free(&answer);
+ } else {
+ ei_x_buff answer;
+ DEBUGF(("Success when connecting.{%d,%d}\n",com_sock,erl_errno));
+ ei_x_new(&answer);
+ ei_x_format(&answer,"~i",com_sock);
+ send_bin_term(&answer);
+ ei_x_free(&answer);
+ }
+
+cleanup:
+
+ if (listen_sock >= 0) {
+ closesocket(listen_sock);
+ }
+ if (epmd_sock >= 0) {
+ closesocket(epmd_sock);
+ }
+ if (com_sock >= 0) {
+ closesocket(com_sock);
+ }
+
+ if (nodename != NULL) {
+ free(nodename);
+ }
+ if (cookie != NULL) {
+ free(cookie);
+ }
+ CLOSE_DEBUGFILE();
+ report(1);
+}
+
diff --git a/lib/erl_interface/test/erl_connect_SUITE.erl b/lib/erl_interface/test/erl_connect_SUITE.erl
new file mode 100644
index 0000000000..0d6539d98f
--- /dev/null
+++ b/lib/erl_interface/test/erl_connect_SUITE.erl
@@ -0,0 +1,134 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2000-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_connect_SUITE).
+
+-include("test_server.hrl").
+-include("erl_connect_SUITE_data/erl_connect_test_cases.hrl").
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,
+ erl_send/1,erl_reg_send/1, erl_send_cookie_file/1]).
+
+-import(runner, [get_term/1,send_term/2]).
+
+all(suite) ->
+ [erl_send,erl_reg_send,erl_send_cookie_file].
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?t:minutes(0.25)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+erl_send(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = erl_connect(P, node()),
+
+ ?line ok = erl_send(P, Fd, self(), AMsg={a,message}),
+ ?line receive AMsg -> ok end,
+
+ ?line 0 = erl_close_connection(P,Fd),
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+erl_send_cookie_file(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skip,"Skipped on VxWorks"};
+ _ ->
+ ?line P = runner:start(?interpret),
+ ?line 1 = erl_connect_init(P, 42, '', 0),
+ ?line {ok,Fd} = erl_connect(P, node()),
+
+ ?line ok = erl_send(P, Fd, self(), AMsg={a,message}),
+ ?line receive AMsg -> ok end,
+
+ ?line 0 = erl_close_connection(P,Fd),
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok
+ end.
+
+erl_reg_send(Config) when is_list(Config) ->
+ ?line P = runner:start(?interpret),
+ ?line 1 = erl_connect_init(P, 42, erlang:get_cookie(), 0),
+ ?line {ok,Fd} = erl_connect(P, node()),
+
+ ARegName = a_strange_registred_name,
+ ?line register(ARegName, self()),
+ ?line ok = erl_reg_send(P, Fd, ARegName, AMsg={another,[strange],message}),
+ ?line receive AMsg -> ok end,
+
+ ?line 0 = erl_close_connection(P,Fd),
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%%% Interface functions for erl_interface functions.
+
+erl_connect_init(P, Num, Cookie, Creation) ->
+ send_command(P, erl_connect_init, [Num,Cookie,Creation]),
+ case get_term(P) of
+ {term,Int} when is_integer(Int) -> Int
+ end.
+
+erl_connect(P, Node) ->
+ send_command(P, erl_connect, [Node]),
+ case get_term(P) of
+ {term,{Fd,_}} when Fd >= 0 -> {ok,Fd};
+ {term,{-1,Errno}} -> {error,Errno}
+ end.
+
+erl_close_connection(P, FD) ->
+ send_command(P, erl_close_connection, [FD]),
+ case get_term(P) of
+ {term,Int} when is_integer(Int) -> Int
+ end.
+
+erl_send(P, Fd, To, Msg) ->
+ send_command(P, erl_send, [Fd,To,Msg]),
+ get_send_result(P).
+
+erl_reg_send(P, Fd, To, Msg) ->
+ send_command(P, erl_reg_send, [Fd,To,Msg]),
+ get_send_result(P).
+
+get_send_result(P) ->
+ case get_term(P) of
+ {term,{1,_}} -> ok;
+ {term,{-1,Errno}} -> {error,Errno};
+ {term,{Res,Errno}}->
+ io:format("Return value: ~p\nerl_errno: ~p", [Res,Errno]),
+ ?t:fail(bad_return_value)
+ end.
+
+send_command(P, Name, Args) ->
+ runner:send_term(P, {Name,list_to_tuple(Args)}).
+
+
+
+
+
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..09c00e7b8c
--- /dev/null
+++ b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+erl_connect_test_decl.c: erl_connect_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run erl_connect_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..047a734ecb
--- /dev/null
+++ b/lib/erl_interface/test/erl_connect_SUITE_data/Makefile.src
@@ -0,0 +1,41 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/runner@obj@ \
+ $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+OBJS = erl_connect_test@obj@ erl_connect_test_decl@obj@
+
+all: erl_connect_test@exe@
+
+erl_connect_test@exe@: $(OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(OBJS) $(LIBFLAGS)
+
+clean:
+ $(RM) $(OBJS)
+ $(RM) erl_connect_test@exe@
diff --git a/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c b/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c
new file mode 100644
index 0000000000..02304260b8
--- /dev/null
+++ b/lib/erl_interface/test/erl_connect_SUITE_data/erl_connect_test.c
@@ -0,0 +1,202 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2000-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the functions in erl_connect.c.
+ * Author: Bjorn Gustavsson
+ *
+ * See the erl_connect_SUITE.erl file for a "table of contents".
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "runner.h"
+
+static void cmd_erl_connect_init(ETERM* args);
+static void cmd_erl_connect(ETERM* args);
+static void cmd_erl_send(ETERM* args);
+static void cmd_erl_reg_send(ETERM* args);
+static void cmd_erl_close_connection(ETERM *args);
+
+static void send_errno_result(int value);
+
+static struct {
+ char* name;
+ int num_args; /* Number of arguments. */
+ void (*func)(ETERM* args);
+} commands[] = {
+ "erl_connect_init", 3, cmd_erl_connect_init,
+ "erl_connect", 1, cmd_erl_connect,
+ "erl_close_connection", 1, cmd_erl_close_connection,
+ "erl_send", 3, cmd_erl_send,
+ "erl_reg_send", 3, cmd_erl_reg_send,
+};
+
+
+/*
+ * Sends a list contaning all data types to the Erlang side.
+ */
+
+TESTCASE(interpret)
+{
+ ETERM* term;
+
+ erl_init(NULL, 0);
+
+ outer_loop:
+
+ term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+ ETERM* Func;
+ ETERM* Args;
+ int i;
+
+ if (!ERL_IS_TUPLE(term) || ERL_TUPLE_SIZE(term) != 2) {
+ fail("term should be a tuple of size 2");
+ }
+
+ Func = erl_element(1, term);
+ if (!ERL_IS_ATOM(Func)) {
+ fail("function name should be an atom");
+ }
+ Args = erl_element(2, term);
+ if (!ERL_IS_TUPLE(Args)) {
+ fail("function arguments should be a tuple");
+ }
+ erl_free_term(term);
+ for (i = 0; i < sizeof(commands)/sizeof(commands[0]); i++) {
+ int n = strlen(commands[i].name);
+ if (ERL_ATOM_SIZE(Func) != n) {
+ continue;
+ }
+ if (memcmp(ERL_ATOM_PTR(Func), commands[i].name, n) == 0) {
+ erl_free_term(Func);
+ if (ERL_TUPLE_SIZE(Args) != commands[i].num_args) {
+ fail("wrong number of arguments");
+ }
+ commands[i].func(Args);
+ erl_free_term(Args);
+ goto outer_loop;
+ }
+ }
+ fail("bad command");
+ }
+}
+
+#define VERIFY_TYPE(Test, Term) \
+if (!Test(Term)) { \
+ fail("wrong type for " #Term); \
+} else { \
+}
+
+static void
+cmd_erl_connect_init(ETERM* args)
+{
+ ETERM* number;
+ ETERM* res;
+ ETERM* cookie;
+ char cookie_buffer[256];
+
+ number = ERL_TUPLE_ELEMENT(args, 0);
+ VERIFY_TYPE(ERL_IS_INTEGER, number);
+ cookie = ERL_TUPLE_ELEMENT(args, 1);
+ VERIFY_TYPE(ERL_IS_ATOM, cookie);
+ if (ERL_ATOM_SIZE(cookie) == 0) {
+ res = erl_mk_int(erl_connect_init(ERL_INT_VALUE(number), 0, 0));
+ } else {
+ memcpy(cookie_buffer, ERL_ATOM_PTR(cookie), ERL_ATOM_SIZE(cookie));
+ cookie_buffer[ERL_ATOM_SIZE(cookie)] = '\0';
+ res = erl_mk_int(erl_connect_init(ERL_INT_VALUE(number),
+ cookie_buffer, 0));
+ }
+ send_term(res);
+ erl_free_term(res);
+}
+
+static void
+cmd_erl_connect(ETERM* args)
+{
+ ETERM* node;
+ char node_buffer[256];
+
+ node = ERL_TUPLE_ELEMENT(args, 0);
+ VERIFY_TYPE(ERL_IS_ATOM, node);
+ memcpy(node_buffer, ERL_ATOM_PTR(node), ERL_ATOM_SIZE(node));
+ node_buffer[ERL_ATOM_SIZE(node)] = '\0';
+ send_errno_result(erl_connect(node_buffer));
+}
+
+static void
+cmd_erl_close_connection(ETERM* args)
+{
+ ETERM* number;
+ ETERM* res;
+
+ number = ERL_TUPLE_ELEMENT(args, 0);
+ VERIFY_TYPE(ERL_IS_INTEGER, number);
+ res = erl_mk_int(erl_close_connection(ERL_INT_VALUE(number)));
+ send_term(res);
+ erl_free_term(res);
+}
+
+static void
+cmd_erl_send(ETERM* args)
+{
+ ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+ ETERM* to = ERL_TUPLE_ELEMENT(args, 1);
+ ETERM* msg = ERL_TUPLE_ELEMENT(args, 2);
+
+ VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+ send_errno_result(erl_send(ERL_INT_VALUE(fd_term), to, msg));
+}
+
+static void
+cmd_erl_reg_send(ETERM* args)
+{
+ ETERM* fd_term = ERL_TUPLE_ELEMENT(args, 0);
+ ETERM* to = ERL_TUPLE_ELEMENT(args, 1);
+ ETERM* msg = ERL_TUPLE_ELEMENT(args, 2);
+ char reg_name[256];
+
+ VERIFY_TYPE(ERL_IS_INTEGER, fd_term);
+ VERIFY_TYPE(ERL_IS_ATOM, to);
+ memcpy(reg_name, ERL_ATOM_PTR(to), ERL_ATOM_SIZE(to));
+ reg_name[ERL_ATOM_SIZE(to)] = '\0';
+ send_errno_result(erl_reg_send(ERL_INT_VALUE(fd_term), reg_name, msg));
+}
+
+static void
+send_errno_result(int value)
+{
+ ETERM* res_array[2];
+ ETERM* res_tuple;
+
+ res_array[0] = erl_mk_int(value);
+ res_array[1] = erl_mk_int(erl_errno);
+ res_tuple = erl_mk_tuple(res_array, 2);
+ send_term(res_tuple);
+ erl_free_term(res_array[0]);
+ erl_free_term(res_array[1]);
+ erl_free_term(res_tuple);
+}
diff --git a/lib/erl_interface/test/erl_eterm_SUITE.erl b/lib/erl_interface/test/erl_eterm_SUITE.erl
new file mode 100644
index 0000000000..634e2f9aa0
--- /dev/null
+++ b/lib/erl_interface/test/erl_eterm_SUITE.erl
@@ -0,0 +1,1136 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_eterm_SUITE).
+
+-include("test_server.hrl").
+-include("erl_eterm_SUITE_data/eterm_test_cases.hrl").
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% The tests are organised as follows:
+%%%
+%%% 1. Basic tests (encoding, decoding, memory allocation).
+%%% 2. Constructing terms (the erl_mk_xxx() functions and erl_copy_term()).
+%%% 3. Extracting & info functions (erl_hd(), erl_length() etc).
+%%% 4. I/O list functions.
+%%% 5. Miscellanous functions.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-export([all/1, build_terms/1, round_trip_conversion/1,
+ decode_terms/1, decode_float/1,
+ t_erl_mk_int/1, t_erl_mk_list/1,
+ basic_copy/1,
+ t_erl_cons/1,
+ t_erl_mk_atom/1,
+ t_erl_mk_binary/1,
+ t_erl_mk_empty_list/1,
+ t_erl_mk_float/1,
+ t_erl_mk_pid/1,
+ t_erl_mk_xpid/1,
+ t_erl_mk_port/1,
+ t_erl_mk_xport/1,
+ t_erl_mk_ref/1,
+ t_erl_mk_long_ref/1,
+ t_erl_mk_string/1,
+ t_erl_mk_estring/1,
+ t_erl_mk_tuple/1,
+ t_erl_mk_uint/1,
+ t_erl_mk_var/1,
+ t_erl_size/1,
+ t_erl_var_content/1,
+ t_erl_element/1,
+ t_erl_length/1, t_erl_hd/1, t_erl_tl/1,
+ type_checks/1, extractor_macros/1,
+ t_erl_iolist_length/1, t_erl_iolist_to_binary/1,
+ t_erl_iolist_to_string/1,
+ erl_print_term/1, print_string/1,
+ t_erl_free_compound/1,
+ high_chaparal/1,
+ broken_data/1,
+ cnode_1/1]).
+
+-export([start_cnode/1]).
+
+-import(runner, [get_term/1]).
+
+%% This test suite controls the running of the C language functions
+%% in eterm_test.c and print_term.c.
+
+all(suite) -> [build_terms, round_trip_conversion,
+ decode_terms, decode_float,
+ t_erl_mk_int, t_erl_mk_list,
+ basic_copy,
+ t_erl_mk_atom,
+ t_erl_mk_binary,
+ t_erl_mk_empty_list,
+ t_erl_mk_float,
+ t_erl_mk_pid,
+ t_erl_mk_xpid,
+ t_erl_mk_port,
+ t_erl_mk_xport,
+ t_erl_mk_ref,
+ t_erl_mk_long_ref,
+ t_erl_mk_string,
+ t_erl_mk_estring,
+ t_erl_mk_tuple,
+ t_erl_mk_uint,
+ t_erl_mk_var,
+ t_erl_size,
+ t_erl_var_content,
+ t_erl_element,
+ t_erl_cons,
+ t_erl_length, t_erl_hd, t_erl_tl,
+ type_checks, extractor_macros,
+ t_erl_iolist_length, t_erl_iolist_to_binary,
+ t_erl_iolist_to_string,
+ erl_print_term, print_string,
+ t_erl_free_compound,
+ high_chaparal,
+ broken_data,
+ cnode_1].
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% 1. B a s i c t e s t s
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% This test asks the C function to construct all data types in
+%% a list and verifies that the result is as expected.
+
+build_terms(suite) -> [];
+build_terms(Config) when is_list(Config) ->
+ ?line P = runner:start(?build_terms),
+ ?line {term, Term} = get_term(P),
+ ?line io:format("Received: ~p", [Term]),
+ ?line [ARefLN, ARef, APortLN, APort, APidLN, APid,
+ {element1, 42, 767}, "A string",
+ 1, -1, 0, 3.0, ABin, 'I am an atom'] = Term,
+ ?line "A binary" = binary_to_list(ABin),
+ ?line case ARef of
+ R when is_reference(R), node(R) == kalle@localhost -> ok
+ end,
+ ?line case ARefLN of
+ R1 when is_reference(R1), node(R1) == abcdefghijabcdefghij@localhost -> ok
+ end,
+ ?line case APort of
+ Port when is_port(Port), node(Port) == kalle@localhost -> ok
+ end,
+ ?line case APortLN of
+ Port1 when is_port(Port1), node(Port1) == abcdefghijabcdefghij@localhost -> ok
+ end,
+ ?line case APid of
+ Pid when is_pid(Pid), node(Pid) == kalle@localhost -> ok
+ end,
+ ?line case APidLN of
+ Pid1 when is_pid(Pid1), node(Pid1) == abcdefghijabcdefghij@localhost -> ok
+ end,
+
+ ?line runner:recv_eot(P),
+ ok.
+
+%% This test is run entirely in C code.
+
+round_trip_conversion(suite) -> [];
+round_trip_conversion(Config) when is_list(Config) ->
+ ?line runner:test(?round_trip_conversion),
+ ok.
+
+%% This test sends a list of all data types to the C code function,
+%% which decodes it and verifies it.
+
+decode_terms(suite) -> [];
+decode_terms(Config) when is_list(Config) ->
+ ?line Dummy1 = list_to_atom(filename:join(?config(priv_dir, Config),
+ dummy_file1)),
+ ?line Dummy2 = list_to_atom(filename:join(?config(priv_dir, Config),
+ dummy_file2)),
+ ?line Port1 = open_port(Dummy1, [out]),
+ ?line Port2 = open_port(Dummy2, [out]),
+ ?line ABinary = list_to_binary("A binary"),
+ ?line Terms = [make_ref(), make_ref(),
+ Port1, Port2,
+ self(), self(),
+ {element1, 42, 767}, "A string",
+ 1, -1, 0, 3.0, ABinary, 'I am an atom'],
+
+ ?line P = runner:start(?decode_terms),
+ ?line runner:send_term(P, Terms),
+ ?line runner:recv_eot(P),
+
+ ok.
+
+%% Decodes the floating point number 3.1415.
+
+decode_float(suite) -> [];
+decode_float(Config) when is_list(Config) ->
+ ?line P = runner:start(?decode_float),
+ ?line runner:send_term(P, 3.1415),
+ ?line runner:recv_eot(P),
+ ok.
+
+%% Tests the erl_free_compound() function.
+
+t_erl_free_compound(suite) -> [];
+t_erl_free_compound(Config) when is_list(Config) ->
+ ?line runner:test(?t_erl_free_compound),
+ ok.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% 2. C o n s t r u c t i n g t e r m s
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% This tests the erl_mk_list() function.
+
+t_erl_mk_list(suite) -> [];
+t_erl_mk_list(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_list),
+
+ ?line {term, []} = get_term(P),
+ ?line {term, [abc]} = get_term(P),
+ ?line {term, [abcdef, 42]} = get_term(P),
+ ?line {term, [0.0, 23, [], 3.1415]} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_int() function.
+
+t_erl_mk_int(suite) -> [];
+t_erl_mk_int(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_int),
+
+ ?line {term, 0} = get_term(P),
+ ?line {term, 127} = get_term(P),
+ ?line {term, 128} = get_term(P),
+ ?line {term, 255} = get_term(P),
+ ?line {term, 256} = get_term(P),
+
+ ?line {term, 16#FFFF} = get_term(P),
+ ?line {term, 16#10000} = get_term(P),
+
+ ?line {term, 16#07FFFFFF} = get_term(P),
+ ?line {term, 16#0FFFFFFF} = get_term(P),
+ ?line {term, 16#1FFFFFFF} = get_term(P),
+ ?line {term, 16#3FFFFFFF} = get_term(P),
+ ?line {term, 16#7FFFFFFF} = get_term(P),
+
+ ?line {term, 16#08000000} = get_term(P),
+ ?line {term, 16#10000000} = get_term(P),
+ ?line {term, 16#20000000} = get_term(P),
+ ?line {term, 16#40000000} = get_term(P),
+
+
+ ?line {term, -16#07FFFFFF} = get_term(P),
+ ?line {term, -16#0FFFFFFF} = get_term(P),
+ ?line {term, -16#1FFFFFFF} = get_term(P),
+ ?line {term, -16#3FFFFFFF} = get_term(P),
+ ?line {term, -16#7FFFFFFF} = get_term(P),
+
+ ?line {term, -16#08000000} = get_term(P),
+ ?line {term, -16#10000000} = get_term(P),
+ ?line {term, -16#20000000} = get_term(P),
+ ?line {term, -16#40000000} = get_term(P),
+
+ ?line {term, -16#08000001} = get_term(P),
+ ?line {term, -16#10000001} = get_term(P),
+ ?line {term, -16#20000001} = get_term(P),
+ ?line {term, -16#40000001} = get_term(P),
+
+ ?line {term, -16#08000002} = get_term(P),
+ ?line {term, -16#10000002} = get_term(P),
+ ?line {term, -16#20000002} = get_term(P),
+ ?line {term, -16#40000002} = get_term(P),
+
+ ?line {term, -1999999999} = get_term(P),
+ ?line {term, -2000000000} = get_term(P),
+ ?line {term, -2000000001} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% Basic test of erl_copy_term().
+
+basic_copy(suite) -> [];
+basic_copy(Config) when is_list(Config) ->
+ ?line runner:test(?basic_copy),
+ ok.
+
+
+%% This tests the erl_mk_tuple() function.
+
+t_erl_mk_tuple(suite) -> [];
+t_erl_mk_tuple(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_tuple),
+
+ ?line {term, {madonna, 21, 'mad donna', 12}} = get_term(P),
+ ?line {term, {'Madonna',21,{children,{"Isabella",2}},
+ {'home page',"http://www.madonna.com/"}}} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_atom() function.
+
+t_erl_mk_atom(suite) -> [];
+t_erl_mk_atom(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_atom),
+
+ ?line {term, madonna} = (get_term(P)),
+ ?line {term, 'Madonna'} = (get_term(P)),
+ ?line {term, 'mad donna'} = (get_term(P)),
+ ?line {term, '_madonna_'} = (get_term(P)),
+ ?line {term, '/home/madonna/tour_plan'} = (get_term(P)),
+ ?line {term, 'http://www.madonna.com/tour_plan'} = (get_term(P)),
+ ?line {term, '\'madonna\''} = (get_term(P)),
+ ?line {term, '\"madonna\"'} = (get_term(P)),
+ ?line {term, '\\madonna\\'} = (get_term(P)),
+ ?line {term, '{madonna,21,\'mad donna\',12}'} = (get_term(P)),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_binary() function.
+
+t_erl_mk_binary(suite) -> [];
+t_erl_mk_binary(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_binary),
+
+ ?line {term, Bin} = (get_term(P)),
+ ?line "{madonna,21,'mad donna',1234.567.890, !#$%&/()=?+-@, \" \\}" =
+ binary_to_list(Bin),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_empty_list() function.
+
+t_erl_mk_empty_list(suite) -> [];
+t_erl_mk_empty_list(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_empty_list),
+
+ ?line {term, []} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_float() function.
+
+t_erl_mk_float(suite) -> [];
+t_erl_mk_float(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped, "Floating point numbers never compare equal on PPC"};
+ _ ->
+ ?line P = runner:start(?t_erl_mk_float),
+ ?line {term, {3.1415, 1.999999, 2.000000, 2.000001,
+ 2.000002, 12345.67890}} =
+ get_term(P),
+ ?line runner:recv_eot(P),
+ ok
+ end.
+
+
+%% This tests the erl_mk_pid() function.
+
+t_erl_mk_pid(suite) -> [];
+t_erl_mk_pid(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_pid),
+
+ ?line {term, A_pid} = (get_term(P)),
+ ?line {pid, kalle@localhost, 3, 2} = nc2vinfo(A_pid),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+t_erl_mk_xpid(suite) -> [];
+t_erl_mk_xpid(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_xpid),
+
+ ?line {term, A_pid} = (get_term(P)),
+ ?line {pid, kalle@localhost, 32767, 8191} = nc2vinfo(A_pid),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_port() function.
+
+t_erl_mk_port(suite) -> [];
+t_erl_mk_port(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_port),
+
+ ?line {term, A_port} = (get_term(P)),
+ ?line {port, kalle@localhost, 4} = nc2vinfo(A_port),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+t_erl_mk_xport(suite) -> [];
+t_erl_mk_xport(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_xport),
+
+ ?line {term, A_port} = (get_term(P)),
+ ?line {port, kalle@localhost, 268435455} = nc2vinfo(A_port),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_ref() function.
+
+t_erl_mk_ref(suite) -> [];
+t_erl_mk_ref(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_ref),
+
+ ?line {term, A_ref} = (get_term(P)),
+ ?line {ref, kalle@localhost, _Length, [6]} = nc2vinfo(A_ref),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+t_erl_mk_long_ref(suite) -> [];
+t_erl_mk_long_ref(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_long_ref),
+
+ ?line {term, A_ref} = (get_term(P)),
+ ?line {ref, kalle@localhost, _Length, [4294967295,4294967295,262143]}
+ = nc2vinfo(A_ref),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_string() function.
+
+t_erl_mk_string(suite) -> [];
+t_erl_mk_string(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_string),
+
+ ?line {term, "madonna"} = (get_term(P)),
+ ?line {term, "Madonna"} = (get_term(P)),
+ ?line {term, "mad donna"} = (get_term(P)),
+ ?line {term, "_madonna_"} = (get_term(P)),
+ ?line {term, "/home/madonna/tour_plan"} = (get_term(P)),
+ ?line {term, "http://www.madonna.com/tour_plan"} = (get_term(P)),
+ ?line {term, "\'madonna\'"} = (get_term(P)),
+ ?line {term, "\"madonna\""} = (get_term(P)),
+ ?line {term, "\\madonna\\"} = (get_term(P)),
+ ?line {term, "{madonna,21,'mad donna',12}"} = (get_term(P)),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_estring() function.
+
+t_erl_mk_estring(suite) -> [];
+t_erl_mk_estring(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_estring),
+
+ ?line {term, "madonna"} = (get_term(P)),
+ ?line {term, "Madonna"} = (get_term(P)),
+ ?line {term, "mad donna"} = (get_term(P)),
+ ?line {term, "_madonna_"} = (get_term(P)),
+ ?line {term, "/home/madonna/tour_plan"} = (get_term(P)),
+ ?line {term, "http://www.madonna.com/tour_plan"} = (get_term(P)),
+ ?line {term, "\'madonna\'"} = (get_term(P)),
+ ?line {term, "\"madonna\""} = (get_term(P)),
+ ?line {term, "\\madonna\\"} = (get_term(P)),
+ ?line {term, "{madonna,21,'mad donna',12}"} = (get_term(P)),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_uint() function.
+
+t_erl_mk_uint(suite) -> [];
+t_erl_mk_uint(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_uint),
+
+ ?line {term, 54321} = (get_term(P)),
+ ?line {term, 2147483647} = (get_term(P)),
+ ?line {term, 2147483648} = (get_term(P)),
+ ?line {term, 2147483649} = (get_term(P)),
+ ?line {term, 2147483650} = (get_term(P)),
+ ?line {term, 4294967295} = (get_term(P)),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_mk_var() function.
+
+t_erl_mk_var(suite) -> [];
+t_erl_mk_var(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_mk_var),
+
+ ?line {term, 1} = (get_term(P)),
+ ?line {term, 0} = (get_term(P)),
+ ?line {term, 1} = (get_term(P)),
+ ?line {term, 0} = (get_term(P)),
+ ?line {term, 1} = (get_term(P)),
+ ?line {term, 0} = (get_term(P)),
+ ?line {term, 1} = (get_term(P)),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_cons() function.
+
+t_erl_cons(suite) -> [];
+t_erl_cons(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_cons),
+
+ ?line {term, [madonna, 21]} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% 3. E x t r a c t i n g & i n f o f u n c t i o n s
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the erl_length() function.
+
+t_erl_length(suite) -> [];
+t_erl_length(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_length),
+
+ ?line 0 = erl_length(P, []),
+ ?line 1 = erl_length(P, [a]),
+ ?line 2 = erl_length(P, [a, b]),
+ ?line 3 = erl_length(P, [a, b, c]),
+
+ ?line 4 = erl_length(P, [a, [x, y], c, []]),
+
+ ?line -1 = erl_length(P, [a|b]),
+ ?line -1 = erl_length(P, a),
+
+ ?line runner:finish(P),
+ ok.
+
+%% Invokes the erl_length() function.
+
+erl_length(Port, List) ->
+ call_erl_function(Port, List).
+
+%% Tests the erl_hd() function.
+
+t_erl_hd(suite) -> [];
+t_erl_hd(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_hd),
+
+ ?line 'NULL' = erl_hd(P, 42),
+ ?line 'NULL' = erl_hd(P, abc),
+ ?line 'NULL' = erl_hd(P, []),
+
+ ?line [] = erl_hd(P, [[], a]),
+ ?line a = erl_hd(P, [a]),
+ ?line a = erl_hd(P, [a, b]),
+ ?line a = erl_hd(P, [a, b, c]),
+ ?line a = erl_hd(P, [a|b]),
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+%% Invokes the erl_hd() function.
+
+erl_hd(Port, List) ->
+ call_erl_function(Port, List).
+
+%% Tests the erl_tail() function.
+
+t_erl_tl(suite) -> [];
+t_erl_tl(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_tl),
+
+ ?line 'NULL' = erl_tl(P, 42),
+ ?line 'NULL' = erl_tl(P, abc),
+ ?line 'NULL' = erl_tl(P, []),
+
+ ?line [] = erl_tl(P, [a]),
+ ?line [b] = erl_tl(P, [a, b]),
+ ?line [b, c] = erl_tl(P, [a, b, c]),
+
+ ?line b = erl_tl(P, [a|b]),
+
+ ?line runner:send_eot(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+%% Invokes the erl_tail() function in erl_interface.
+
+erl_tl(Port, List) ->
+ call_erl_function(Port, List).
+
+%% Tests the type checking macros (done in the C program).
+
+type_checks(suite) -> [];
+type_checks(Config) when is_list(Config) ->
+ ?line runner:test(?type_checks),
+ ok.
+
+%% Tests the extractor macros (done in the C program).
+
+extractor_macros(suite) -> [];
+extractor_macros(Config) when is_list(Config) ->
+ ?line runner:test(?extractor_macros),
+ ok.
+
+
+%% This tests the erl_size() function.
+
+t_erl_size(suite) -> [];
+t_erl_size(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_size),
+
+ ?line {term, 0} = (get_term(P)),
+ ?line {term, 4} = (get_term(P)),
+
+ ?line {term, 0} = (get_term(P)),
+ ?line {term, 27} = (get_term(P)),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_var_content() function.
+
+t_erl_var_content(suite) -> [];
+t_erl_var_content(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_var_content),
+
+ ?line {term, 17} = (get_term(P)),
+ ?line {term, "http://www.madonna.com"} = (get_term(P)),
+ ?line {term, 2} = (get_term(P)),
+ ?line {term, "http://www.madonna.com"} = (get_term(P)),
+ ?line {term, 2} = (get_term(P)),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+%% This tests the erl_element() function.
+
+t_erl_element(suite) -> [];
+t_erl_element(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_element),
+
+ ?line {term, madonna} = get_term(P),
+ ?line {term, 21} = get_term(P),
+ ?line {term, 'mad donna'} = get_term(P),
+ ?line {term, 12} = get_term(P),
+
+ ?line {term, 'Madonna'} = get_term(P),
+ ?line {term, 21} = get_term(P),
+ ?line {term, {children,{"Isabella",2}}} = get_term(P),
+ ?line {term, {'home page',"http://www.madonna.com/"}} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% 4. I / O l i s t f u n c t i o n s
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Tests the erl_iolist_length() function.
+
+t_erl_iolist_length(suite) -> [];
+t_erl_iolist_length(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_iolist_length),
+
+ %% Flat lists.
+
+ ?line 0 = erl_iolist_length(P, []),
+ ?line 1 = erl_iolist_length(P, [10]),
+ ?line 2 = erl_iolist_length(P, [10, 20]),
+ ?line 3 = erl_iolist_length(P, [10, 20, 30]),
+ ?line 256 = erl_iolist_length(P, lists:seq(0, 255)),
+
+ %% Deep lists.
+
+ ?line 0 = erl_iolist_length(P, [[]]),
+ ?line 1 = erl_iolist_length(P, [[], 42]),
+ ?line 1 = erl_iolist_length(P, [42, []]),
+ ?line 2 = erl_iolist_length(P, [42, [], 45]),
+
+ ?line 3 = erl_iolist_length(P, [42, [90], 45]),
+ ?line 3 = erl_iolist_length(P, [[42, [90]], 45]),
+ ?line 3 = erl_iolist_length(P, [[42, [90]], 45]),
+
+ %% List with binaries.
+
+ ?line 0 = erl_iolist_length(P, [list_to_binary([])]),
+ ?line 0 = erl_iolist_length(P, [[], list_to_binary([])]),
+ ?line 1 = erl_iolist_length(P, [[1], list_to_binary([])]),
+ ?line 1 = erl_iolist_length(P, [[], list_to_binary([2])]),
+ ?line 2 = erl_iolist_length(P, [[42], list_to_binary([2])]),
+ ?line 4 = erl_iolist_length(P, [[42], list_to_binary([2, 3, 4])]),
+
+ %% Binaries as tail.
+
+ ?line 0 = erl_iolist_length(P, [[]| list_to_binary([])]),
+ ?line 1 = erl_iolist_length(P, [[1]| list_to_binary([])]),
+ ?line 1 = erl_iolist_length(P, [[]| list_to_binary([2])]),
+ ?line 2 = erl_iolist_length(P, [[42]| list_to_binary([2])]),
+
+ %% Binaries only.
+
+ ?line 0 = erl_iolist_length(P, list_to_binary("")),
+ ?line 1 = erl_iolist_length(P, list_to_binary([1])),
+ ?line 2 = erl_iolist_length(P, list_to_binary([1, 2])),
+
+ %% Illegal cases.
+
+ ?line -1 = erl_iolist_length(P, [42|43]),
+ ?line -1 = erl_iolist_length(P, a),
+
+ ?line -1 = erl_iolist_length(P, [a]),
+ ?line -1 = erl_iolist_length(P, [256]),
+ ?line -1 = erl_iolist_length(P, [257]),
+ ?line -1 = erl_iolist_length(P, [-1]),
+ ?line -1 = erl_iolist_length(P, [-2]),
+ ?line -1 = erl_iolist_length(P, [-127]),
+ ?line -1 = erl_iolist_length(P, [-128]),
+
+ ?line runner:finish(P),
+ ok.
+
+%% Invokes the erl_iolist_length() function.
+
+erl_iolist_length(Port, List) ->
+ call_erl_function(Port, List).
+
+%% Tests the erl_iolist_to_binary() function.
+
+t_erl_iolist_to_binary(suite) -> [];
+t_erl_iolist_to_binary(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_iolist_to_binary),
+
+ %% Flat lists.
+
+ ?line [] = iolist_to_list(P, []),
+ ?line [10] = iolist_to_list(P, [10]),
+ ?line [10, 20] = iolist_to_list(P, [10, 20]),
+ ?line [10, 20, 30] = iolist_to_list(P, [10, 20, 30]),
+ ?line AllBytes = lists:seq(0, 255),
+ ?line AllBytes = iolist_to_list(P, AllBytes),
+
+ %% Deep lists.
+
+ ?line [] = iolist_to_list(P, [[]]),
+ ?line [42] = iolist_to_list(P, [[], 42]),
+ ?line [42] = iolist_to_list(P, [42, []]),
+ ?line [42, 45] = iolist_to_list(P, [42, [], 45]),
+
+ ?line [42, 90, 45] = iolist_to_list(P, [42, [90], 45]),
+ ?line [42, 90, 45] = iolist_to_list(P, [[42, [90]], 45]),
+ ?line [42, 90, 45] = iolist_to_list(P, [[42, [90]], 45]),
+
+ %% List with binaries.
+
+ ?line [] = iolist_to_list(P, [list_to_binary([])]),
+ ?line [] = iolist_to_list(P, [[], list_to_binary([])]),
+ ?line [1] = iolist_to_list(P, [[1], list_to_binary([])]),
+ ?line [2] = iolist_to_list(P, [[], list_to_binary([2])]),
+ ?line [42, 2] = iolist_to_list(P, [[42], list_to_binary([2])]),
+ ?line [42, 2, 3, 4] = iolist_to_list(P, [[42], list_to_binary([2, 3, 4])]),
+
+ %% Binaries as tail.
+
+ ?line [] = iolist_to_list(P, [[]| list_to_binary([])]),
+ ?line [1] = iolist_to_list(P, [[1]| list_to_binary([])]),
+ ?line [2] = iolist_to_list(P, [[]| list_to_binary([2])]),
+ ?line [42, 2] = iolist_to_list(P, [[42]| list_to_binary([2])]),
+
+ %% Binaries only.
+
+ ?line [] = iolist_to_list(P, list_to_binary("")),
+ ?line [1] = iolist_to_list(P, list_to_binary([1])),
+ ?line [1, 2] = iolist_to_list(P, list_to_binary([1, 2])),
+
+ %% Illegal cases.
+
+ ?line 'NULL' = iolist_to_list(P, [42|43]),
+ ?line 'NULL' = iolist_to_list(P, a),
+
+ ?line 'NULL' = iolist_to_list(P, [a]),
+ ?line 'NULL' = iolist_to_list(P, [256]),
+ ?line 'NULL' = iolist_to_list(P, [257]),
+ ?line 'NULL' = iolist_to_list(P, [-1]),
+ ?line 'NULL' = iolist_to_list(P, [-2]),
+ ?line 'NULL' = iolist_to_list(P, [-127]),
+ ?line 'NULL' = iolist_to_list(P, [-128]),
+
+ ?line runner:finish(P),
+ ok.
+
+iolist_to_list(Port, Term) ->
+ case call_erl_function(Port, Term) of
+ 'NULL' ->
+ 'NULL';
+ Bin when is_binary(Bin) ->
+ binary_to_list(Bin)
+ end.
+
+%% Tests the erl_iolist_to_string() function.
+
+t_erl_iolist_to_string(suite) -> [];
+t_erl_iolist_to_string(Config) when is_list(Config) ->
+ ?line P = runner:start(?t_erl_iolist_to_string),
+
+ %% Flat lists.
+
+ ?line [0] = iolist_to_string(P, []),
+ ?line [10, 0] = iolist_to_string(P, [10]),
+ ?line [10, 20, 0] = iolist_to_string(P, [10, 20]),
+ ?line [10, 20, 30, 0] = iolist_to_string(P, [10, 20, 30]),
+ ?line AllBytes = lists:seq(1, 255)++[0],
+ ?line AllBytes = iolist_to_string(P, lists:seq(1, 255)),
+
+ %% Deep lists.
+
+ ?line [0] = iolist_to_string(P, [[]]),
+ ?line [42, 0] = iolist_to_string(P, [[], 42]),
+ ?line [42, 0] = iolist_to_string(P, [42, []]),
+ ?line [42, 45, 0] = iolist_to_string(P, [42, [], 45]),
+
+ ?line [42, 90, 45, 0] = iolist_to_string(P, [42, [90], 45]),
+ ?line [42, 90, 45, 0] = iolist_to_string(P, [[42, [90]], 45]),
+ ?line [42, 90, 45, 0] = iolist_to_string(P, [[42, [90]], 45]),
+
+ %% List with binaries.
+
+ ?line [0] = iolist_to_string(P, [list_to_binary([])]),
+ ?line [0] = iolist_to_string(P, [[], list_to_binary([])]),
+ ?line [1, 0] = iolist_to_string(P, [[1], list_to_binary([])]),
+ ?line [2, 0] = iolist_to_string(P, [[], list_to_binary([2])]),
+ ?line [42, 2, 0] = iolist_to_string(P, [[42], list_to_binary([2])]),
+ ?line [42, 2, 3, 4, 0] = iolist_to_string(P, [[42],
+ list_to_binary([2, 3, 4])]),
+
+ %% Binaries as tail.
+
+ ?line [0] = iolist_to_string(P, [[]| list_to_binary([])]),
+ ?line [1, 0] = iolist_to_string(P, [[1]| list_to_binary([])]),
+ ?line [2, 0] = iolist_to_string(P, [[]| list_to_binary([2])]),
+ ?line [42, 2, 0] = iolist_to_string(P, [[42]| list_to_binary([2])]),
+
+ %% Binaries only.
+
+ ?line [0] = iolist_to_string(P, list_to_binary("")),
+ ?line [1, 0] = iolist_to_string(P, list_to_binary([1])),
+ ?line [1, 2, 0] = iolist_to_string(P, list_to_binary([1, 2])),
+
+ %% Illegal cases.
+
+ ?line 'NULL' = iolist_to_string(P, [0]),
+ ?line 'NULL' = iolist_to_string(P, [65, 0, 66]),
+ ?line 'NULL' = iolist_to_string(P, [65, 66, 67, 0]),
+
+ ?line 'NULL' = iolist_to_string(P, [42|43]),
+ ?line 'NULL' = iolist_to_string(P, a),
+
+ ?line 'NULL' = iolist_to_string(P, [a]),
+ ?line 'NULL' = iolist_to_string(P, [256]),
+ ?line 'NULL' = iolist_to_string(P, [257]),
+ ?line 'NULL' = iolist_to_string(P, [-1]),
+ ?line 'NULL' = iolist_to_string(P, [-2]),
+ ?line 'NULL' = iolist_to_string(P, [-127]),
+ ?line 'NULL' = iolist_to_string(P, [-128]),
+
+ ?line runner:finish(P),
+ ok.
+
+%% Invokes the erl_iolist_to_string() function.
+
+iolist_to_string(Port, Term) ->
+ runner:send_term(Port, Term),
+ case get_term(Port) of
+ {bytes, Result} -> Result;
+ 'NULL' -> 'NULL'
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%
+%%% 5. M i s c e l l a n o u s T e s t s
+%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+erl_print_term(suite) -> [];
+erl_print_term(doc) -> "Tests the erl_print_term() function";
+erl_print_term(Config) when is_list(Config) ->
+ ?line PrintTerm = print_term(Config),
+ ?line P = open_port({spawn, PrintTerm}, [stream]),
+
+ %% Lists.
+
+ ?line print(P, "[]", []),
+ ?line print(P, "[a]", [a]),
+ ?line print(P, "[[a]]", [[a]]),
+ ?line print(P, "[[]]", [[]]),
+ ?line print(P, "[a,b,c]", [a,b,c]),
+ ?line print(P, "[a,b|c]", [a,b|c]),
+ ?line print(P, "[a,[],c]", [a,[],c]),
+ ?line print(P, "[a,[1000,1],c]", [a,[1000,1],c]),
+
+ %% Tuples.
+
+ ?line print(P, "{}", {}),
+ ?line print(P, "{ok}", {ok}),
+ ?line print(P, "{1,2,3}", {1, 2, 3}),
+
+ %% Pids.
+
+ ?line {_X, Y, Z} = split_pid(self()),
+ ?line PidString = lists:flatten(io_lib:format("<~s.~w.~w>",
+ [node(), Y, Z])),
+ ?line print(P, PidString, self()),
+
+ ?line unlink(P),
+ ?line exit(P, die),
+ ok.
+
+split_pid(Pid) when is_pid(Pid) ->
+ split_pid(pid_to_list(Pid), 0, []).
+
+split_pid([$<|Rest], Cur, Result) ->
+ split_pid(Rest, Cur, Result);
+split_pid([Digit|Rest], Cur, Result) when $0 =< Digit, Digit =< $9 ->
+ split_pid(Rest, 10*Cur+Digit-$0, Result);
+split_pid([$.|Rest], Cur, Result) ->
+ split_pid(Rest, 0, Result++[Cur]);
+split_pid([$>], Cur, Result) ->
+ list_to_tuple(Result++[Cur]).
+
+print_string(suite) -> [];
+print_string(doc) -> "Test printing a string with erl_print_term()";
+print_string(Config) when is_list(Config) ->
+ ?line PrintTerm = print_term(Config),
+ ?line P = open_port({spawn, PrintTerm}, [stream]),
+
+ %% Strings.
+
+ ?line print(P, "\"ABC\"", "ABC"),
+ ?line {11, "\"\\tABC\\r\\n\""} = print(P, "\tABC\r\n"),
+
+ %% Not strings.
+
+ ?line print(P, "[65,66,67,0]", "ABC\000"),
+
+ ?line unlink(P),
+ ?line exit(P, die),
+ ok.
+
+print(Port, TermString, Term) ->
+ Length = length(TermString),
+ {Length, TermString} = print(Port, Term).
+
+%% This function uses the erl_print_term() function in erl_interface
+%% to print a term.
+%% Returns: {NumChars, Chars}
+
+print(Port, Term) ->
+ Bin = term_to_binary(Term),
+ Size = size(Bin),
+ Port ! {self(), {command, [Size div 256, Size rem 256, Bin]}},
+ collect_line(Port, []).
+
+collect_line(Port, Result) ->
+ receive
+ {Port, {data, Data}} ->
+ case lists:reverse(Data) of
+ [$\n|Rest] ->
+ collect_line1(Rest++Result, []);
+ Chars ->
+ collect_line(Port, Chars++Result)
+ end
+ after test_server:seconds(5) ->
+ test_server:fail("No response from C program")
+ end.
+
+collect_line1([$\r|Rest], Result) ->
+ {list_to_integer(Result), lists:reverse(Rest)};
+collect_line1([C|Rest], Result) ->
+ collect_line1(Rest, [C|Result]).
+
+%% Test case submitted by Per Lundgren, ERV.
+
+high_chaparal(suite) -> [];
+high_chaparal(Config) when is_list(Config) ->
+ ?line P = runner:start(?high_chaparal),
+ ?line {term, [hello, world]} = get_term(P),
+ ?line runner:recv_eot(P),
+ ok.
+
+%% OTP-7448
+broken_data(suite) -> [];
+broken_data(Config) when is_list(Config) ->
+ ?line P = runner:start(?broken_data),
+ ?line runner:recv_eot(P),
+ ok.
+
+%% This calls a C function with one parameter and returns the result.
+
+call_erl_function(Port, Term) ->
+ runner:send_term(Port, Term),
+ case get_term(Port) of
+ {term, Result} -> Result;
+ 'NULL' -> 'NULL'
+ end.
+
+print_term(Config) when is_list(Config) ->
+ filename:join(?config(data_dir, Config), "print_term").
+
+
+
+%%% We receive a ref from the cnode, and expect it to be a long ref.
+%%% We also send a ref we created ourselves, and expect to get it
+%%% back, without having been mutated into short form. We must take
+%%% care then to check the actual returned ref, and not the original
+%%% one, which is equal to it.
+cnode_1(suite) -> [];
+cnode_1(doc) -> "Tests involving cnode: sends a long ref from a cnode to us";
+cnode_1(Config) when is_list(Config) ->
+ ?line Cnode = filename:join(?config(data_dir, Config), "cnode"),
+ ?line register(mip, self()),
+ ?line spawn_link(?MODULE, start_cnode, [Cnode]),
+ ?line Ref1 = get_ref(),
+ io:format("Ref1 ~p~n", [Ref1]),
+ ?line check_ref(Ref1),
+ ?line Ref2 = make_ref(),
+ ?line receive
+ Pid -> Pid
+ end,
+ ?line Fun1 = fun(X) -> {Pid, X} end, % sneak in a fun test here
+ %?line Fun1 = {wait_with_funs, new_dist_format},
+ ?line Term = {Ref2, Fun1, {1,2,3,4,5,6,7,8,9,10}},
+ %% A term which will overflow the original buffer used in 'cnode'.
+ ?line Pid ! Term,
+ ?line receive
+ Term2 ->
+ io:format("received ~p~n", [Term2]),
+ case Term2 of
+ Term ->
+ {Ref22,_,_} = Term2,
+ ?line check_ref(Ref22);
+ X ->
+ test_server:fail({receive1,X})
+ end
+ after 5000 ->
+ test_server:fail(receive1)
+ end,
+ ?line receive
+ Pid ->
+ ok;
+ Y ->
+ test_server:fail({receive1,Y})
+ after 5000 ->
+ test_server:fail(receive2)
+ end,
+ ?line io:format("ref = ~p~n", [Ref1]),
+ ?line check_ref(Ref1),
+ ok.
+
+check_ref(Ref) ->
+ case bin_ext_type(Ref) of
+ 101 ->
+ test_server:fail(oldref);
+ 114 ->
+ ok;
+ Type ->
+ test_server:fail({type, Type})
+ end.
+
+bin_ext_type(T) ->
+ [131, Type | _] = binary_to_list(term_to_binary(T)),
+ Type.
+
+get_ref() ->
+ receive
+ X when is_reference(X) ->
+ X
+ after 5000 ->
+ test_server:fail({cnode, timeout})
+ end.
+
+start_cnode(Cnode) ->
+ open_port({spawn, Cnode ++ " " ++ atom_to_list(erlang:get_cookie())}, []),
+ rec_cnode().
+
+rec_cnode() ->
+ receive
+ X ->
+ io:format("from cnode: ~p~n", [X]),
+ rec_cnode()
+ end.
+
+nc2vinfo(Pid) when is_pid(Pid) ->
+ ?line [_NodeStr, NumberStr, SerialStr]
+ = string:tokens(pid_to_list(Pid), "<.>"),
+ ?line Number = list_to_integer(NumberStr),
+ ?line Serial = list_to_integer(SerialStr),
+ ?line {pid, node(Pid), Number, Serial};
+nc2vinfo(Port) when is_port(Port) ->
+ ?line ["#Port", _NodeStr, NumberStr]
+ = string:tokens(erlang:port_to_list(Port), "<.>"),
+ ?line Number = list_to_integer(NumberStr),
+ ?line {port, node(Port), Number};
+nc2vinfo(Ref) when is_reference(Ref) ->
+ ?line ["#Ref", _NodeStr | NumStrList]
+ = string:tokens(erlang:ref_to_list(Ref), "<.>"),
+ ?line {Len, RevNumList} = lists:foldl(fun ("0", {N, []}) ->
+ {N+1, []};
+ (IStr, {N, Is}) ->
+ {N+1,
+ [list_to_integer(IStr)|Is]}
+ end,
+ {0, []},
+ NumStrList),
+ ?line {ref, node(Ref), Len, lists:reverse(RevNumList)};
+nc2vinfo(Other) ->
+ ?line {badarg, Other}.
+
+
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..0f25fcc0a9
--- /dev/null
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+eterm_test_decl.c: eterm_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run eterm_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..89931c7701
--- /dev/null
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/Makefile.src
@@ -0,0 +1,50 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/runner@obj@ \
+ $(LIBERL) $(LIBEI) @erl_interface_sock_libs@ @LIBS@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+ETERM_OBJS = eterm_test@obj@ eterm_test_decl@obj@
+CNODE_OBJS = cnode@obj@
+PRINT_OBJS = print_term@obj@
+EXE_FILES = eterm_test@exe@ print_term@exe@ cnode@exe@
+
+all: $(EXE_FILES)
+
+eterm_test@exe@: $(ETERM_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(ETERM_OBJS) $(LIBFLAGS)
+
+cnode@exe@: $(CNODE_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(CNODE_OBJS) $(LIBFLAGS)
+
+print_term@exe@: print_term@obj@ $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(PRINT_OBJS) $(LIBFLAGS)
+
+clean:
+ $(RM) $(ETERM_OBJS) $(CNODE_OBJS) $(PRINT_OBJS)
+ $(RM) $(EXE_FILES)
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c b/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c
new file mode 100644
index 0000000000..133f35f4bd
--- /dev/null
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/cnode.c
@@ -0,0 +1,166 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1999-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "ei.h"
+#include "erl_interface.h"
+
+#define MSGSIZE 13
+
+#define SELF(fd) erl_mk_pid(erl_thisnodename(),fd,0,erl_thiscreation())
+
+#ifdef VXWORKS
+#define MAIN cnode
+#else
+#define MAIN main
+#endif
+
+/* FIXME uses mix och ei and erl_interface */
+
+/*
+ A small cnode.
+ To be called from the test case erl_eterm_SUITE:cnode_1.
+
+ 1) Set up connection to node 'test_server' on the same host.
+ All sends are done to a registered process named 'mip'.
+ 2) Create a long ref and send it.
+ 3) Create a pid for ourselves and send it.
+ 4) Receive a message.
+ 5) Send back the message part of the message.
+ 6) Send back the 'to' part of the message.
+ 7) Exit.
+*/
+
+MAIN(int argc, char **argv)
+
+{
+ unsigned char *msgbufp;
+ int msgsize;
+ ErlMessage msg;
+ char msgbuf[MSGSIZE];
+ char buf[100];
+ char buf1[100];
+ char buf2[100];
+ int ix;
+ int s;
+ int fd;
+ char node[80];
+ char server[80];
+ char host[80];
+ int number;
+ ETERM *ref, *ref1, *ref2;
+
+ erl_init(NULL, 0);
+
+ number = 1;
+ if (argc >= 2) {
+ s = erl_connect_init(number, argv[1], 0);
+ } else {
+ s = erl_connect_init(number, (char *) 0, 0);
+ }
+ gethostname(host, sizeof(host));
+ sprintf(node, "c%d@%s", number, host);
+
+ printf("s = %d\n", s);
+
+ sprintf(server, "test_server@%s", host);
+ fd = erl_connect(server);
+ printf("fd = %d\n", fd);
+
+/* printf("dist = %d\n", erl_distversion(fd)); */
+
+#if 1
+ ref = erl_mk_long_ref(node, 4711, 113, 98, 0);
+#else
+ ref = erl_mk_ref(node, 4711, 0);
+#endif
+ printf("ref = %d\n", ref);
+
+ s = erl_reg_send(fd, "mip", ref);
+ printf("s = %d\n", s);
+
+ {
+ ETERM* emsg;
+ emsg = SELF(fd);
+ erl_reg_send(fd,"mip",emsg);
+ erl_free_term(emsg);
+ }
+
+ msgsize = 4;
+ msgbufp = (unsigned char *) malloc(msgsize);
+
+ do {
+#if 0
+ s = erl_receive_msg(fd, msgbuf, MSGSIZE, &msg);
+#else
+ s = erl_xreceive_msg(fd, &msgbufp, &msgsize, &msg);
+#endif
+ switch (s) {
+ case ERL_TICK:
+ printf("tick\n");
+ break;
+ case ERL_ERROR:
+ printf("error\n");
+ break;
+ case ERL_MSG:
+ printf("msg %d\n", msgsize);
+ break;
+ default:
+ printf("unknown result %d\n", s);
+ break;
+ }
+ } while (s == ERL_TICK);
+
+ s = erl_reg_send(fd, "mip", msg.msg);
+ printf("s = %d\n", s);
+ s = erl_reg_send(fd, "mip", msg.to);
+ printf("s = %d\n", s);
+#if 0
+ /* from = NULL! */
+ s = erl_reg_send(fd, "mip", msg.from);
+ printf("s = %d\n", s);
+#endif
+
+#if 0
+ /* Unused code which tests refs in some ways. */
+ ix = 0;
+ s = ei_encode_term(buf, &ix, ref);
+ printf ("ei encode = %d, ix = %d\n", s, ix);
+
+ /* Compare old and new ref equal */
+ ref1 = erl_mk_long_ref(node, 4711, 113, 98, 0);
+ ref2 = erl_mk_ref(node, 4711, 0);
+ s = erl_encode(ref1, buf1);
+ printf("enc1 s = %d\n", s);
+ s = erl_encode(ref2, buf2);
+ printf("enc2 s = %d\n", s);
+ s = erl_compare_ext(buf1, buf2);
+ printf("comp s = %d\n", s);
+
+ /* Compare, in another way */
+ s = erl_match(ref1, ref2);
+ printf("match s = %d\n", s);
+#endif
+
+ erl_close_connection(fd);
+
+ return 0;
+}
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
new file mode 100644
index 0000000000..6b2ec8f766
--- /dev/null
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/eterm_test.c
@@ -0,0 +1,1511 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the functions in erl_eterm.c and erl_malloc.c.
+ * Author: Bjorn Gustavsson
+ *
+ * See the erl_eterm_SUITE.erl file for a "table of contents".
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "runner.h"
+
+/*
+ * Find out which version of erl_interface we are using.
+ */
+
+#ifdef ERL_IS_STRING
+#undef NEW_ERL_INTERFACE
+#else
+#define NEW_ERL_INTERFACE
+#endif
+
+void dump_term (FILE *fp, ETERM *t);
+
+static ETERM* all_types();
+
+/***********************************************************************
+ *
+ * 1. B a s i c t e s t s
+ *
+ ***********************************************************************/
+
+/*
+ * Sends a list contaning all data types to the Erlang side.
+ */
+
+TESTCASE(build_terms)
+{
+ ETERM* t;
+
+ erl_init(NULL, 0);
+ t = all_types();
+ send_term(t);
+ report(1);
+}
+
+/*
+ * Converts an Erlang term to the external term format and back again.
+ */
+
+TESTCASE(round_trip_conversion)
+{
+ ETERM* original;
+ ETERM* new_terms;
+ char encoded[16*1024];
+ int n;
+
+ erl_init(NULL, 0);
+ original = all_types();
+ if (erl_encode(original, encoded) == 0)
+ {
+ fail("failed to encode terms");
+ } else if ((new_terms = erl_decode(encoded)) == NULL)
+ {
+ fail("failed to decode terms");
+ } else if (!erl_match(original, new_terms))
+ {
+ fail("decoded terms didn't match original");
+ }
+
+ erl_free_term(original);
+ erl_free_term(new_terms);
+ report(1);
+}
+
+/*
+ * Decodes data from the Erlang side and verifies.
+ */
+
+TESTCASE(decode_terms)
+{
+ ETERM* terms;
+ char* message;
+
+ erl_init(NULL, 0);
+ terms = get_term();
+ if (terms == NULL) {
+ fail("unexpected end of file");
+ } else {
+ ETERM* all;
+ ETERM* p;
+ ETERM* t;
+ int i;
+
+ all = p = all_types();
+ t = terms;
+
+ /*
+ * XXX For now, skip the reference, pid, and port, because
+ * the match will fail. Must write code here to do some other
+ * validating.
+ */
+
+ for (i=0; i<6; i++) {
+
+ p = erl_tl(p);
+ t = erl_tl(t);
+ erl_free_term(p);
+ erl_free_term(t);
+
+ }
+
+ /*
+ * Match the tail of the lists.
+ */
+
+ if (!erl_match(p, t))
+ {
+ fail("Received terms didn't match expected");
+ }
+ erl_free_term(all);
+ erl_free_term(terms);
+ report(1);
+ }
+}
+
+/*
+ * Decodes a float from the Erlang side and verifies.
+ */
+
+TESTCASE(decode_float)
+{
+ ETERM* afnum;
+ ETERM* efnum;
+ int result;
+
+ erl_init(NULL, 0);
+ afnum = get_term();
+ efnum = erl_mk_float(3.1415);
+ result = erl_match(efnum, afnum);
+ erl_free_term(afnum);
+ erl_free_term(efnum);
+ report(result);
+}
+
+/*
+ * Tests the erl_free_compound() function.
+ */
+
+TESTCASE(t_erl_free_compound)
+{
+ ETERM* t;
+
+ erl_init(NULL, 0);
+
+ t = all_types();
+ erl_free_compound(t);
+ report(1);
+}
+
+
+/***********************************************************************
+ *
+ * 2. C o n s t r u c t i n g t e r m s
+ *
+ ***********************************************************************/
+
+/*
+ * Makes various integers, and sends them to Erlang for verification.
+ */
+
+TESTCASE(t_erl_mk_int)
+{
+#define SEND_INT(i) \
+ do { \
+ ETERM* t = erl_mk_int(i); \
+ send_term(t); \
+ } while (0);
+
+ erl_init(NULL, 0);
+
+ SEND_INT(0);
+ SEND_INT(127);
+ SEND_INT(128);
+ SEND_INT(255);
+ SEND_INT(256);
+
+ SEND_INT(0xFFFF);
+ SEND_INT(0x10000);
+
+ SEND_INT(0x07FFFFFF);
+ SEND_INT(0x0FFFFFFF);
+ SEND_INT(0x1FFFFFFF);
+ SEND_INT(0x3FFFFFFF);
+ SEND_INT(0x7FFFFFFF);
+
+ SEND_INT(0x08000000);
+ SEND_INT(0x10000000);
+ SEND_INT(0x20000000);
+ SEND_INT(0x40000000);
+
+ SEND_INT(-0x07FFFFFF);
+ SEND_INT(-0x0FFFFFFF);
+ SEND_INT(-0x1FFFFFFF);
+ SEND_INT(-0x3FFFFFFF);
+ SEND_INT(-0x7FFFFFFF);
+
+ SEND_INT(-0x08000000);
+ SEND_INT(-0x10000000);
+ SEND_INT(-0x20000000);
+ SEND_INT(-0x40000000);
+
+ SEND_INT(-0x08000001);
+ SEND_INT(-0x10000001);
+ SEND_INT(-0x20000001);
+ SEND_INT(-0x40000001);
+
+ SEND_INT(-0x08000002);
+ SEND_INT(-0x10000002);
+ SEND_INT(-0x20000002);
+ SEND_INT(-0x40000002);
+
+ SEND_INT(-1999999999);
+ SEND_INT(-2000000000);
+ SEND_INT(-2000000001);
+
+ report(1);
+}
+
+
+/*
+ * Makes lists of various sizes, and sends them to Erlang for verification.
+ */
+
+TESTCASE(t_erl_mk_list)
+{
+ ETERM* a[4];
+
+ erl_init(NULL, 0);
+
+ /*
+ * Empty list.
+ */
+
+ send_term(erl_mk_list(a, 0));
+
+ /*
+ * One element: [abc]
+ */
+
+ a[0] = erl_mk_atom("abc");
+ send_term(erl_mk_list(a, 1));
+ erl_free_term(a[0]);
+
+ /*
+ * Two elements: [abcdef, 42].
+ */
+
+ a[0] = erl_mk_atom("abcdef");
+ a[1] = erl_mk_int(42);
+ send_term(erl_mk_list(a, 2));
+ erl_free_term(a[0]);
+ erl_free_term(a[1]);
+
+ /*
+ * Four elements.
+ */
+
+ a[0] = erl_mk_float(0.0);
+ a[1] = erl_mk_int(23);
+ a[2] = erl_mk_empty_list();
+ a[3] = erl_mk_float(3.1415);
+ send_term(erl_mk_list(a, 4));
+ erl_free_term(a[0]);
+ erl_free_term(a[1]);
+ erl_free_term(a[2]);
+ erl_free_term(a[3]);
+
+ report(1);
+}
+
+/*
+ * A basic test of erl_copy_term().
+ */
+
+TESTCASE(basic_copy)
+{
+ ETERM* original;
+ ETERM* copy;
+ int result;
+
+ erl_init(NULL, 0);
+ original = all_types();
+ copy = erl_copy_term(original);
+ if (copy == NULL) {
+ fail("erl_copy_term() failed");
+ } else if (!erl_match(original, copy))
+ {
+ fail("copy doesn't match original");
+ }
+
+ erl_free_term(original);
+ erl_free_term(copy);
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_atom().
+ */
+
+TESTCASE(t_erl_mk_atom)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_atom("madonna"));
+ send_term(erl_mk_atom("Madonna"));
+ send_term(erl_mk_atom("mad donna"));
+ send_term(erl_mk_atom("_madonna_"));
+ send_term(erl_mk_atom("/home/madonna/tour_plan"));
+ send_term(erl_mk_atom("http://www.madonna.com/tour_plan"));
+ send_term(erl_mk_atom("\'madonna\'"));
+ send_term(erl_mk_atom("\"madonna\""));
+ send_term(erl_mk_atom("\\madonna\\"));
+ send_term(erl_mk_atom("{madonna,21,'mad donna',12}"));
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_binary().
+ */
+
+TESTCASE(t_erl_mk_binary)
+{
+
+ char* string;
+ erl_init(NULL, 0);
+
+ string = "{madonna,21,'mad donna',1234.567.890, !#$%&/()=?+-@, \" \\}";
+ send_term(erl_mk_binary(string,strlen(string)));
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_empty_list().
+ */
+
+TESTCASE(t_erl_mk_empty_list)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_empty_list());
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_float().
+ */
+
+TESTCASE(t_erl_mk_float)
+{
+ ETERM* arr[6];
+ ETERM* emsg;
+
+ erl_init(NULL, 0);
+
+ arr[0] = erl_mk_float(3.1415);
+ arr[1] = erl_mk_float(1.999999);
+ arr[2] = erl_mk_float(2.000000);
+ arr[3] = erl_mk_float(2.000001);
+ arr[4] = erl_mk_float(2.000002);
+ arr[5] = erl_mk_float(12345.67890);
+ emsg = (erl_mk_tuple(arr,6));
+
+ send_term(emsg);
+
+ erl_free_array(arr,6);
+ /* emsg already freed by send_term() */
+ /* erl_free_term(emsg); */
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_pid().
+ */
+
+TESTCASE(t_erl_mk_pid)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_pid("kalle@localhost", 3, 2, 1));
+ report(1);
+}
+
+/*
+ * A basic test of erl_mk_pid().
+ */
+
+TESTCASE(t_erl_mk_xpid)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_pid("kalle@localhost", 32767, 8191, 1));
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_port().
+ */
+
+TESTCASE(t_erl_mk_port)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_port("kalle@localhost", 4, 1));
+ report(1);
+}
+
+/*
+ * A basic test of erl_mk_port().
+ */
+
+TESTCASE(t_erl_mk_xport)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_port("kalle@localhost", 268435455, 1));
+ report(1);
+}
+
+/*
+ * A basic test of erl_mk_ref().
+ */
+
+TESTCASE(t_erl_mk_ref)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_ref("kalle@localhost", 6, 1));
+ report(1);
+}
+
+/*
+ * A basic test of erl_mk_long_ref().
+ */
+
+
+TESTCASE(t_erl_mk_long_ref)
+{
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_long_ref("kalle@localhost",
+ 4294967295, 4294967295, 262143,
+ 1));
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_string().
+ */
+
+TESTCASE(t_erl_mk_string)
+{
+
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_string("madonna"));
+ send_term(erl_mk_string("Madonna"));
+ send_term(erl_mk_string("mad donna"));
+ send_term(erl_mk_string("_madonna_"));
+ send_term(erl_mk_string("/home/madonna/tour_plan"));
+ send_term(erl_mk_string("http://www.madonna.com/tour_plan"));
+ send_term(erl_mk_string("\'madonna\'"));
+ send_term(erl_mk_string("\"madonna\""));
+ send_term(erl_mk_string("\\madonna\\"));
+ send_term(erl_mk_string("{madonna,21,'mad donna',12}"));
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_estring().
+ */
+
+TESTCASE(t_erl_mk_estring)
+{
+ char* string;
+ erl_init(NULL, 0);
+
+ string = "madonna";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "Madonna";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "mad donna";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "_madonna_";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "/home/madonna/tour_plan";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "http://www.madonna.com/tour_plan";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "\'madonna\'";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "\"madonna\"";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "\\madonna\\";
+ send_term(erl_mk_estring(string,strlen(string)));
+ string = "{madonna,21,'mad donna',12}";
+ send_term(erl_mk_estring(string,strlen(string)));
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_tuple().
+ */
+
+TESTCASE(t_erl_mk_tuple)
+{
+ ETERM* arr[4];
+ ETERM* arr2[2];
+ ETERM* arr3[2];
+ ETERM* arr4[2];
+
+ erl_init(NULL, 0);
+
+ /* {madonna,21,'mad donna',12} */
+ arr[0] = erl_mk_atom("madonna");
+ arr[1] = erl_mk_int(21);
+ arr[2] = erl_mk_atom("mad donna");
+ arr[3] = erl_mk_int(12);
+
+ send_term(erl_mk_tuple(arr,4));
+
+ erl_free_array(arr,4);
+
+
+ /* {'Madonna',21,{children,{"Isabella",2}},{'home page',"http://www.madonna.com/"} */
+ arr4[0] = erl_mk_atom("home page");
+ arr4[1] = erl_mk_string("http://www.madonna.com/");
+
+ arr3[0] = erl_mk_string("Isabella");
+ arr3[1] = erl_mk_int(2);
+
+ arr2[0] = erl_mk_atom("children");
+ arr2[1] = erl_mk_tuple(arr3,2);
+
+ arr[0] = erl_mk_atom("Madonna");
+ arr[1] = erl_mk_int(21);
+ arr[2] = erl_mk_tuple(arr2,2);
+ arr[3] = erl_mk_tuple(arr4,2);
+
+ send_term(erl_mk_tuple(arr,4));
+
+ erl_free_array(arr,4);
+ erl_free_array(arr2,2);
+ erl_free_array(arr3,2);
+ erl_free_array(arr4,2);
+
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_uint().
+ */
+
+TESTCASE(t_erl_mk_uint)
+{
+ unsigned i;
+
+ erl_init(NULL, 0);
+
+ send_term(erl_mk_uint(54321));
+ i = 2147483647;
+ send_term(erl_mk_uint(i));
+ send_term(erl_mk_uint(i+1));
+ send_term(erl_mk_uint(i+2));
+ send_term(erl_mk_uint(i+3));
+ send_term(erl_mk_uint(i+i+1));
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_mk_var().
+ */
+
+TESTCASE(t_erl_mk_var)
+{
+ ETERM* mk_var;
+ ETERM* term;
+ ETERM* term2;
+ ETERM* arr[4];
+ ETERM* arr_term[2];
+ ETERM* mk_var_tuple;
+ ETERM* term_tuple;
+
+ erl_init(NULL, 0);
+
+
+ /* match unbound/bound variable against an integer */
+ term = erl_mk_int(17);
+ term2 = erl_mk_int(2);
+ mk_var = erl_mk_var("New_var");
+ send_term(erl_mk_int(erl_match(mk_var, term))); /* should be ok */
+ send_term(erl_mk_int(erl_match(mk_var, term2))); /* should fail */
+ send_term(erl_mk_int(erl_match(mk_var, term))); /* should be ok */
+ send_term(erl_mk_int(erl_match(mk_var, term2))); /* should fail */
+ erl_free_term(mk_var);
+ erl_free_term(term);
+ erl_free_term(term2);
+
+ /* match unbound variable against a tuple */
+ arr[0] = erl_mk_atom("madonna");
+ arr[1] = erl_mk_int(21);
+ arr[2] = erl_mk_atom("mad donna");
+ arr[3] = erl_mk_int(12);
+ mk_var = erl_mk_var("New_var");
+ term = erl_mk_tuple(arr,4);
+ send_term(erl_mk_int(erl_match(mk_var, term))); /* should be ok */
+ erl_free_term(mk_var);
+ erl_free_term(term);
+ erl_free_array(arr,4);
+
+
+ /* match (twice) unbound variable against an incorrect tuple */
+ arr[0] = erl_mk_var("New_var");
+ arr[1] = erl_mk_var("New_var");
+ arr_term[0] = erl_mk_int(17);
+ arr_term[1] = erl_mk_int(27);
+ mk_var_tuple = erl_mk_tuple(arr,2);
+ term_tuple = erl_mk_tuple(arr_term,2);
+ send_term(erl_mk_int(erl_match(mk_var_tuple, term_tuple))); /* should fail */
+ erl_free_array(arr,2);
+ erl_free_array(arr_term,2);
+ erl_free_term(mk_var_tuple);
+ erl_free_term(term_tuple);
+
+
+ /* match (twice) unbound variable against a correct tuple */
+ arr[0] = erl_mk_var("New_var");
+ arr[1] = erl_mk_var("New_var");
+ arr_term[0] = erl_mk_int(17);
+ arr_term[1] = erl_mk_int(17);
+ mk_var_tuple = erl_mk_tuple(arr,2);
+ term_tuple = erl_mk_tuple(arr_term,2);
+ send_term(erl_mk_int(erl_match(mk_var_tuple, term_tuple))); /* should be ok */
+ erl_free_array(arr,2);
+ erl_free_array(arr_term,2);
+ erl_free_term(mk_var_tuple);
+ erl_free_term(term_tuple);
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_size().
+ */
+
+TESTCASE(t_erl_size)
+{
+ ETERM* arr[4];
+ ETERM* tuple;
+ ETERM* bin;
+ char* string;
+
+ erl_init(NULL, 0);
+
+ /* size of a tuple */
+ tuple = erl_format("{}");
+ send_term(erl_mk_int(erl_size(tuple)));
+ erl_free_term(tuple);
+
+ arr[0] = erl_mk_atom("madonna");
+ arr[1] = erl_mk_int(21);
+ arr[2] = erl_mk_atom("mad donna");
+ arr[3] = erl_mk_int(12);
+ tuple = erl_mk_tuple(arr,4);
+
+ send_term(erl_mk_int(erl_size(tuple)));
+
+ erl_free_array(arr,4);
+ erl_free_term(tuple);
+
+ /* size of a binary */
+ string = "";
+ bin = erl_mk_binary(string,strlen(string));
+ send_term(erl_mk_int(erl_size(bin)));
+ erl_free_term(bin);
+
+ string = "{madonna,21,'mad donna',12}";
+ bin = erl_mk_binary(string,strlen(string));
+ send_term(erl_mk_int(erl_size(bin)));
+ erl_free_term(bin);
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_var_content().
+ */
+
+TESTCASE(t_erl_var_content)
+{
+ ETERM* mk_var;
+ ETERM* term;
+ ETERM* tuple;
+ ETERM* list;
+ ETERM* a;
+ ETERM* b;
+ ETERM* arr[4];
+ ETERM* arr2[2];
+ ETERM* arr3[2];
+ ETERM* arr4[2];
+
+ erl_init(NULL, 0);
+
+ term = erl_mk_int(17);
+ mk_var = erl_mk_var("Var");
+
+ /* unbound, should return NULL */
+ if (erl_var_content(mk_var,"Var") != NULL)
+ fail("t_erl_var_content() failed");
+
+ erl_match(mk_var, term);
+ send_term(erl_var_content(mk_var,"Var")); /* should return 17 */
+
+ /* integer, should return NULL */
+ if (erl_var_content(term,"Var") != NULL)
+ fail("t_erl_var_content() failed");
+
+ /* unknown variable, should return NULL */
+ if (erl_var_content(mk_var,"Unknown_Var") != NULL)
+ fail("t_erl_var_content() failed");
+
+ erl_free_term(mk_var);
+ erl_free_term(term);
+
+ /* {'Madonna',21,{children,{"Name","Age"}},{"Home_page","Tel_no"}} */
+ arr4[0] = erl_mk_var("Home_page");
+ arr4[1] = erl_mk_var("Tel_no");
+ a = erl_mk_string("http://www.madonna.com");
+ erl_match(arr4[0], a);
+
+ arr3[0] = erl_mk_var("Name");
+ arr3[1] = erl_mk_var("Age");
+ b = erl_mk_int(2);
+ erl_match(arr3[1], b);
+
+ arr2[0] = erl_mk_atom("children");
+ arr2[1] = erl_mk_tuple(arr3,2);
+
+ arr[0] = erl_mk_atom("Madonna");
+ arr[1] = erl_mk_int(21);
+ arr[2] = erl_mk_tuple(arr2,2);
+ arr[3] = erl_mk_tuple(arr4,2);
+
+ tuple = erl_mk_tuple(arr,4);
+
+ /* should return "http://www.madonna.com" */
+ send_term(erl_var_content(tuple,"Home_page"));
+
+ /* unbound, should return NULL */
+ if (erl_var_content(tuple,"Tel_no") != NULL)
+ fail("t_erl_var_content() failed");
+
+ /* unbound, should return NULL */
+ if (erl_var_content(tuple,"Name") != NULL)
+ fail("t_erl_var_content() failed");
+
+ /* should return 2 */
+ send_term(erl_var_content(tuple,"Age"));
+
+ erl_free_array(arr,4);
+ erl_free_array(arr2,2);
+ erl_free_array(arr3,2);
+ erl_free_array(arr4,2);
+ erl_free_term(tuple);
+ erl_free_term(a);
+ erl_free_term(b);
+
+
+ /* [] */
+ list = erl_mk_empty_list();
+ if (erl_var_content(list,"Tel_no") != NULL)
+ fail("t_erl_var_content() failed");
+ erl_free_term(list);
+
+
+ /* ['Madonna',[],{children,{"Name","Age"}},{"Home_page","Tel_no"}] */
+ arr4[0] = erl_mk_var("Home_page");
+ arr4[1] = erl_mk_var("Tel_no");
+ a = erl_mk_string("http://www.madonna.com");
+ erl_match(arr4[0], a);
+
+ arr3[0] = erl_mk_var("Name");
+ arr3[1] = erl_mk_var("Age");
+ b = erl_mk_int(2);
+ erl_match(arr3[1], b);
+
+ arr2[0] = erl_mk_atom("children");
+ arr2[1] = erl_mk_tuple(arr3,2);
+
+ arr[0] = erl_mk_atom("Madonna");
+ arr[1] = erl_mk_empty_list();
+ arr[2] = erl_mk_tuple(arr2,2);
+ arr[3] = erl_mk_tuple(arr4,2);
+
+ list = erl_mk_list(arr,4);
+
+ /* should return "http://www.madonna.com" */
+ send_term(erl_var_content(list,"Home_page"));
+
+ /* unbound, should return NULL */
+ if (erl_var_content(list,"Tel_no") != NULL)
+ fail("t_erl_var_content() failed");
+
+ /* unbound, should return NULL */
+ if (erl_var_content(list,"Name") != NULL)
+ fail("t_erl_var_content() failed");
+
+ /* should return 2 */
+ send_term(erl_var_content(list,"Age"));
+
+ erl_free_array(arr,4);
+ erl_free_array(arr2,2);
+ erl_free_array(arr3,2);
+ erl_free_array(arr4,2);
+ erl_free_term(list);
+ erl_free_term(a);
+ erl_free_term(b);
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_element().
+ */
+
+TESTCASE(t_erl_element)
+{
+ ETERM* arr[4];
+ ETERM* arr2[2];
+ ETERM* arr3[2];
+ ETERM* arr4[2];
+ ETERM* tuple;
+
+ erl_init(NULL, 0);
+
+ arr[0] = erl_mk_atom("madonna");
+ arr[1] = erl_mk_int(21);
+ arr[2] = erl_mk_atom("mad donna");
+ arr[3] = erl_mk_int(12);
+ tuple = erl_mk_tuple(arr,4);
+
+ send_term(erl_element(1,tuple));
+ send_term(erl_element(2,tuple));
+ send_term(erl_element(3,tuple));
+ send_term(erl_element(4,tuple));
+
+ erl_free_array(arr,4);
+ erl_free_term(tuple);
+
+ /* {'Madonna',21,{children,{"Isabella",2}},{'home page',"http://www.madonna.com/"} */
+ arr4[0] = erl_mk_atom("home page");
+ arr4[1] = erl_mk_string("http://www.madonna.com/");
+
+ arr3[0] = erl_mk_string("Isabella");
+ arr3[1] = erl_mk_int(2);
+
+ arr2[0] = erl_mk_atom("children");
+ arr2[1] = erl_mk_tuple(arr3,2);
+
+ arr[0] = erl_mk_atom("Madonna");
+ arr[1] = erl_mk_int(21);
+ arr[2] = erl_mk_tuple(arr2,2);
+ arr[3] = erl_mk_tuple(arr4,2);
+
+ tuple = erl_mk_tuple(arr,4);
+ send_term(erl_element(1,tuple));
+ send_term(erl_element(2,tuple));
+ send_term(erl_element(3,tuple));
+ send_term(erl_element(4,tuple));
+
+ erl_free_term(tuple);
+ erl_free_array(arr,4);
+ erl_free_array(arr2,2);
+ erl_free_array(arr3,2);
+ erl_free_array(arr4,2);
+
+ report(1);
+}
+
+
+/*
+ * A basic test of erl_cons().
+ */
+
+TESTCASE(t_erl_cons)
+{
+ ETERM* list;
+ ETERM* anAtom;
+ ETERM* anInt;
+
+ erl_init(NULL, 0);
+
+ anAtom = erl_mk_atom("madonna");
+ anInt = erl_mk_int(21);
+ list = erl_mk_empty_list();
+ list = erl_cons(anInt, list);
+ send_term(erl_cons(anAtom, list));
+
+ erl_free_term(anAtom);
+ erl_free_term(anInt);
+ erl_free_compound(list);
+
+ report(1);
+}
+
+
+
+
+/***********************************************************************
+ *
+ * 3. E x t r a c t i n g & i n f o f u n c t i o n s
+ *
+ ***********************************************************************/
+
+/*
+ * Calculates the length of each list sent to it and sends back the result.
+ */
+
+TESTCASE(t_erl_length)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ ETERM* term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+ ETERM* len_term;
+
+ len_term = erl_mk_int(erl_length(term));
+ erl_free_term(term);
+ send_term(len_term);
+ }
+ }
+}
+
+/*
+ * Gets the head of each term and sends the result back.
+ */
+
+TESTCASE(t_erl_hd)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ ETERM* term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+ ETERM* head;
+
+ head = erl_hd(term);
+ send_term(head);
+ erl_free_term(term);
+ }
+ }
+}
+
+/*
+ * Gets the tail of each term and sends the result back.
+ */
+
+TESTCASE(t_erl_tl)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ ETERM* term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+ ETERM* tail;
+
+ tail = erl_tl(term);
+ send_term(tail);
+ erl_free_term(term);
+ }
+ }
+}
+
+/*
+ * Checks the type checking macros.
+ */
+
+TESTCASE(type_checks)
+{
+ ETERM* t;
+ ETERM* atom;
+
+ erl_init(NULL, 0);
+ atom = erl_mk_atom("an_atom");
+
+#define TYPE_CHECK(macro, term) \
+ { ETERM* t = term; \
+ if (macro(t)) { \
+ erl_free_term(t); \
+ } else { \
+ fail("Macro " #macro " failed on " #term); \
+ } \
+ }
+
+ TYPE_CHECK(ERL_IS_INTEGER, erl_mk_int(0x7FFFFFFF));
+#ifdef NEW_ERL_INTERFACE
+ TYPE_CHECK(ERL_IS_UNSIGNED_INTEGER, erl_mk_uint(0x7FFFFFFF));
+#endif
+ TYPE_CHECK(ERL_IS_FLOAT, erl_mk_float(5.5));
+ TYPE_CHECK(ERL_IS_ATOM, erl_mk_atom("another_atom"));
+
+ TYPE_CHECK(ERL_IS_EMPTY_LIST, erl_mk_empty_list());
+ TYPE_CHECK(!ERL_IS_EMPTY_LIST, erl_cons(atom, atom));
+
+#ifdef NEW_ERL_INTERFACE
+ TYPE_CHECK(!ERL_IS_CONS, erl_mk_empty_list());
+ TYPE_CHECK(ERL_IS_CONS, erl_cons(atom, atom));
+#endif
+
+ TYPE_CHECK(ERL_IS_LIST, erl_mk_empty_list());
+ TYPE_CHECK(ERL_IS_LIST, erl_cons(atom, atom));
+
+ TYPE_CHECK(ERL_IS_PID, erl_mk_pid("a@a", 42, 1, 1));
+ TYPE_CHECK(ERL_IS_PORT, erl_mk_port("a@a", 42, 1));
+ TYPE_CHECK(ERL_IS_REF, erl_mk_ref("a@a", 42, 1));
+
+ TYPE_CHECK(ERL_IS_BINARY, erl_mk_binary("a", 1));
+ TYPE_CHECK(ERL_IS_TUPLE, erl_mk_tuple(&atom, 1));
+#undef TYPE_CHECK
+
+ erl_free_term(atom);
+
+ report(1);
+}
+
+/*
+ * Checks the extractor macros.
+ */
+
+TESTCASE(extractor_macros)
+{
+ ETERM* t;
+
+ erl_init(NULL, 0);
+
+#ifdef NEW_ERL_INTERFACE
+#define MATCH(a, b) ((a) == (b) ? 1 : fail("bad match: " #a))
+#define STR_MATCH(a, b) (strcmp((a), (b)) ? fail("bad match: " #a) : 0)
+
+ { /* Integer */
+ int anInt = 0x7FFFFFFF;
+ t = erl_mk_int(anInt);
+ MATCH(ERL_INT_VALUE(t), anInt);
+ MATCH(ERL_INT_UVALUE(t), anInt);
+ erl_free_term(t);
+ }
+
+ { /* Float */
+ double aFloat = 3.1415;
+ t = erl_mk_float(aFloat);
+ MATCH(ERL_FLOAT_VALUE(t), aFloat);
+ erl_free_term(t);
+ }
+
+ { /* Atom. */
+ char* aString = "nisse";
+ t = erl_mk_atom(aString);
+ if (memcmp(ERL_ATOM_PTR(t), aString, strlen(aString)) != 0)
+ fail("bad match");
+ MATCH(ERL_ATOM_SIZE(t), strlen(aString));
+ erl_free_term(t);
+ }
+
+ { /* Pid. */
+ char* node = "arne@strider";
+ int number = 42;
+ int serial = 5;
+ int creation = 1;
+
+ t = erl_mk_pid(node, number, serial, creation);
+ STR_MATCH(ERL_PID_NODE(t), node);
+ MATCH(ERL_PID_NUMBER(t), number);
+ MATCH(ERL_PID_SERIAL(t), serial);
+ MATCH(ERL_PID_CREATION(t), creation);
+ erl_free_term(t);
+ }
+
+ { /* Port. */
+ char* node = "kalle@strider";
+ int number = 45;
+ int creation = 1;
+
+ t = erl_mk_port(node, number, creation);
+ STR_MATCH(ERL_PORT_NODE(t), node);
+ MATCH(ERL_PORT_NUMBER(t), number);
+ MATCH(ERL_PORT_CREATION(t), creation);
+ erl_free_term(t);
+ }
+
+ { /* Reference. */
+ char* node = "kalle@strider";
+ int number = 48;
+ int creation = 1;
+
+ t = erl_mk_ref(node, number, creation);
+ STR_MATCH(ERL_REF_NODE(t), node);
+ MATCH(ERL_REF_NUMBER(t), number);
+ MATCH(ERL_REF_CREATION(t), creation);
+ erl_free_term(t);
+ }
+
+ { /* Tuple. */
+ ETERM* arr[2];
+
+ arr[0] = erl_mk_int(51);
+ arr[1] = erl_mk_int(52);
+ t = erl_mk_tuple(arr, ASIZE(arr));
+ MATCH(ERL_TUPLE_SIZE(t), ASIZE(arr));
+ MATCH(ERL_TUPLE_ELEMENT(t, 0), arr[0]);
+ MATCH(ERL_TUPLE_ELEMENT(t, 1), arr[1]);
+ erl_free_array(arr, ASIZE(arr));
+ erl_free_term(t);
+ }
+
+ { /* Binary. */
+ static char bin[] = {1, 2, 3, 0, 4, 5};
+
+ t = erl_mk_binary(bin, ASIZE(bin));
+ MATCH(ERL_BIN_SIZE(t), ASIZE(bin));
+ if (memcmp(ERL_BIN_PTR(t), bin, ASIZE(bin)) != 0)
+ fail("bad match");
+ erl_free_term(t);
+ }
+
+ {
+ ETERM* head = erl_mk_atom("head");
+ ETERM* tail = erl_mk_atom("tail");
+
+ t = erl_cons(head, tail);
+ MATCH(ERL_CONS_HEAD(t), head);
+ MATCH(ERL_CONS_TAIL(t), tail);
+ erl_free_term(head);
+ erl_free_term(tail);
+ erl_free_term(t);
+ }
+#undef MATCH
+#undef STR_MATCH
+#endif
+
+ report(1);
+}
+
+
+
+/***********************************************************************
+ *
+ * 4. I / O l i s t f u n c t i o n s
+ *
+ ***********************************************************************/
+
+/*
+ * Invokes erl_iolist_length() on each term and send backs the result.
+ */
+
+TESTCASE(t_erl_iolist_length)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ ETERM* term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+#ifndef NEW_ERL_INTERFACE
+ fail("Function not present in this version of erl_interface");
+#else
+ ETERM* len_term;
+
+ len_term = erl_mk_int(erl_iolist_length(term));
+ erl_free_term(term);
+ send_term(len_term);
+#endif
+ }
+ }
+}
+
+/*
+ * Invokes erl_iolist_to_binary() on each term and send backs the result.
+ */
+
+TESTCASE(t_erl_iolist_to_binary)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ ETERM* term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+#ifndef NEW_ERL_INTERFACE
+ fail("Function not present in this version of erl_interface");
+#else
+ ETERM* new_term;
+
+ new_term = erl_iolist_to_binary(term);
+
+ erl_free_term(term);
+ send_term(new_term);
+#endif
+ }
+ }
+}
+
+/*
+ * Invokes erl_iolist_to_string() on each term and send backs the result.
+ */
+
+TESTCASE(t_erl_iolist_to_string)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ ETERM* term = get_term();
+
+ if (term == NULL) {
+ report(1);
+ return;
+ } else {
+#ifndef NEW_ERL_INTERFACE
+ fail("Function not present in this version of erl_interface");
+#else
+ char* result;
+
+ result = erl_iolist_to_string(term);
+ erl_free_term(term);
+ if (result != NULL) {
+ send_buffer(result, strlen(result)+1);
+ erl_free(result);
+ } else {
+ send_term(NULL);
+ }
+#endif
+ }
+ }
+}
+
+
+/***********************************************************************
+ *
+ * 5. M i s c e l l a n o u s T e s t s
+ *
+ ***********************************************************************/
+
+/*
+ * Test some combinations of operations to verify that the reference pointers
+ * are handled correctly.
+ *
+ * "Det verkar vara lite High Chaparal med minneshanteringen i erl_interface"
+ * Per Lundgren, ERV.
+ */
+
+TESTCASE(high_chaparal)
+{
+ ETERM *L1, *A1, *L2, *A2, *L3;
+
+ erl_init(NULL, 0);
+
+ L1 = erl_mk_empty_list();
+ A1 = erl_mk_atom("world");
+ L2 = erl_cons(A1, L1);
+ A2 = erl_mk_atom("hello");
+ L3 = erl_cons(A2, L2);
+
+ erl_free_term(L1);
+ erl_free_term(A1);
+ erl_free_term(L2);
+ erl_free_term(A2);
+
+ send_term(L3);
+
+ /* already freed by send_term() */
+ /* erl_free_term(L3);*/
+
+ report(1);
+}
+
+/*
+ * Test erl_decode to recover from broken list data (OTP-7448)
+ */
+TESTCASE(broken_data)
+{
+ ETERM* original;
+ ETERM* new_terms;
+ char encoded[16*1024];
+ int n;
+
+ erl_init(NULL, 0);
+ original = all_types();
+ if ((n=erl_encode(original, encoded)) == 0)
+ {
+ fail("failed to encode terms");
+ } else
+ {
+ int offs = n/2;
+ memset(encoded+offs,0,n-offs); /* destroy */
+
+ if ((new_terms = erl_decode(encoded)) != NULL)
+ {
+ fail("decode accepted broken data");
+ erl_free_term(new_terms);
+ }
+ }
+ erl_free_term(original);
+ report(1);
+}
+
+/*
+ * Returns a list containing instances of all types.
+ *
+ * Be careful changing the contents of the list returned, because both
+ * the build_terms() and decode_terms() test cases depend on it.
+ */
+
+static ETERM*
+all_types(void)
+{
+ ETERM* t;
+ ETERM* terms[3];
+ int i;
+ static char a_binary[] = "A binary";
+
+#define CONS_AND_FREE(expr, tail) \
+ do { \
+ ETERM* term = expr; \
+ ETERM* nl = erl_cons(term, tail); \
+ erl_free_term(term); \
+ erl_free_term(tail); \
+ tail = nl; \
+ } while (0)
+
+ t = erl_mk_empty_list();
+
+ CONS_AND_FREE(erl_mk_atom("I am an atom"), t);
+ CONS_AND_FREE(erl_mk_binary("A binary", sizeof(a_binary)-1), t);
+ CONS_AND_FREE(erl_mk_float(3.0), t);
+ CONS_AND_FREE(erl_mk_int(0), t);
+ CONS_AND_FREE(erl_mk_int(-1), t);
+ CONS_AND_FREE(erl_mk_int(1), t);
+
+ CONS_AND_FREE(erl_mk_string("A string"), t);
+
+ terms[0] = erl_mk_atom("element1");
+ terms[1] = erl_mk_int(42);
+ terms[2] = erl_mk_int(767);
+ CONS_AND_FREE(erl_mk_tuple(terms, ASIZE(terms)), t);
+ for (i = 0; i < ASIZE(terms); i++) {
+ erl_free_term(terms[i]);
+ }
+
+ CONS_AND_FREE(erl_mk_pid("kalle@localhost", 3, 2, 1), t);
+ CONS_AND_FREE(erl_mk_pid("abcdefghijabcdefghij@localhost", 3, 2, 1), t);
+ CONS_AND_FREE(erl_mk_port("kalle@localhost", 4, 1), t);
+ CONS_AND_FREE(erl_mk_port("abcdefghijabcdefghij@localhost", 4, 1), t);
+ CONS_AND_FREE(erl_mk_ref("kalle@localhost", 6, 1), t);
+ CONS_AND_FREE(erl_mk_ref("abcdefghijabcdefghij@localhost", 6, 1), t);
+ return t;
+
+#undef CONS_AND_FREE
+}
+
+/*
+ * Dump (print for debugging) a term. Useful if/when things go wrong.
+ */
+void
+dump_term (FILE *fp, ETERM *t)
+{
+ if (fp == NULL) return;
+
+ fprintf(fp, "#<%p ", t);
+
+ if(t != NULL)
+ {
+ fprintf(fp, "count:%d, type:%d", ERL_COUNT(t), ERL_TYPE(t));
+
+ switch(ERL_TYPE(t))
+ {
+ case ERL_UNDEF:
+ fprintf(fp, "==undef");
+ break;
+ case ERL_INTEGER:
+ fprintf(fp, "==int, val:%d", ERL_INT_VALUE(t));
+ break;
+ case ERL_U_INTEGER:
+ fprintf(fp, "==uint, val:%u", ERL_INT_UVALUE(t));
+ break;
+ case ERL_FLOAT:
+ fprintf(fp, "==float, val:%g", ERL_FLOAT_VALUE(t));
+ break;
+ case ERL_ATOM:
+ fprintf(fp, "==atom, name:%p \"%s\"",
+ ERL_ATOM_PTR(t), ERL_ATOM_PTR(t));
+ break;
+ case ERL_BINARY:
+ fprintf(fp, "==binary, data:%p,%u",
+ ERL_BIN_PTR(t), ERL_BIN_SIZE(t));
+ break;
+ case ERL_PID:
+ fprintf(fp, "==pid, node:%p \"%s\"",
+ ERL_PID_NODE(t), ERL_PID_NODE(t));
+ break;
+ case ERL_PORT:
+ fprintf(fp, "==port, node:%p \"%s\"",
+ ERL_PORT_NODE(t), ERL_PORT_NODE(t));
+ break;
+ case ERL_REF:
+ fprintf(fp, "==ref, node:%p \"%s\"",
+ ERL_REF_NODE(t), ERL_REF_NODE(t));
+ break;
+ case ERL_CONS:
+ fprintf(fp, "==cons");
+ fprintf(fp, ", car:");
+ dump_term(fp, ERL_CONS_HEAD(t));
+ fprintf(fp, ", cdr:");
+ dump_term(fp, ERL_CONS_TAIL(t));
+ break;
+ case ERL_NIL:
+ fprintf(fp, "==nil");
+ break;
+ case ERL_TUPLE:
+ fprintf(fp, "==tuple, elems:%p,%u",
+ ERL_TUPLE_ELEMS(t), ERL_TUPLE_SIZE(t));
+ {
+ size_t i;
+ for(i = 0; i < ERL_TUPLE_SIZE(t); i++)
+ {
+ fprintf(fp, "elem[%u]:", i);
+ dump_term(fp, ERL_TUPLE_ELEMENT(t, i));
+ }
+ }
+ break;
+ case ERL_VARIABLE:
+ fprintf(fp, "==variable, name:%p \"%s\"",
+ ERL_VAR_NAME(t), ERL_VAR_NAME(t));
+ fprintf(fp, ", value:");
+ dump_term(fp, ERL_VAR_VALUE(t));
+ break;
+
+ default:
+ break;
+ }
+ }
+ fprintf(fp, ">");
+}
+
diff --git a/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c b/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c
new file mode 100644
index 0000000000..56e2d43d2f
--- /dev/null
+++ b/lib/erl_interface/test/erl_eterm_SUITE_data/print_term.c
@@ -0,0 +1,129 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Test the erl_print_term() function.
+ * Author: Bjorn Gustavsson
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifndef __WIN32__
+#include <unistd.h>
+#endif
+
+#include "erl_interface.h"
+
+#ifndef __WIN32__
+#define _O_BINARY 0
+#define _setmode(fd, mode)
+#endif
+
+#define HEADER_SIZE 2
+
+static int readn(int, unsigned char*, int);
+
+/*
+ * This program doesn't use the runner, because it needs a packet
+ * on input, but the result will be as a stream of bytes (since
+ * erl_print_term() prints directly on a file).
+ *
+ * Input is a package of with a packet header size of two bytes.
+ *
+ * +------------------------------------------------------------+
+ * | length | Encoded term... |
+ * | (2 bytes) | (as given by "length") |
+ * +------------------------------------------------------------+
+ *
+ * <------------------- length --------------------->
+ *
+ * This program decodes the encoded terms and passes it to
+ * erl_print_term(). Then this program prints
+ *
+ * CR <result> LF
+ *
+ * and waits for a new package. <result> is the return value from
+ * erl_print_term(), formatted as an ASCII string.
+ */
+
+#ifdef VXWORKS
+int print_term()
+#else
+int main()
+#endif
+{
+ _setmode(0, _O_BINARY);
+ _setmode(1, _O_BINARY);
+
+ erl_init(NULL, 0);
+
+ for (;;) {
+ char buf[4*1024];
+ ETERM* term;
+ char* message;
+ int n;
+
+ if (readn(0, buf, 2) <= 0) {
+ /* fprintf(stderr, "error reading message header\n"); */
+ /* actually this is where we leave the infinite loop */
+ exit(1);
+ }
+ n = buf[0] * 256 + buf[1];
+ if (readn(0, buf, n) < 0) {
+ fprintf(stderr, "error reading message contents\n");
+ exit(1);
+ }
+
+ term = erl_decode(buf);
+ if (term == NULL) {
+ fprintf(stderr, "erl_decode() failed\n");
+ exit(1);
+ }
+ n = erl_print_term(stdout, term);
+ erl_free_compound(term);
+ fprintf(stdout,"\r%d\n", n);
+ fflush(stdout);
+ }
+}
+
+/*
+ * Reads len number of bytes.
+ */
+
+static int
+readn(fd, buf, len)
+ int fd; /* File descriptor to read from. */
+ unsigned char *buf; /* Store in this buffer. */
+ int len; /* Number of bytes to read. */
+{
+ int n; /* Byte count in last read call. */
+ int sofar = 0; /* Bytes read so far. */
+
+ do {
+ if ((n = read(fd, buf+sofar, len-sofar)) <= 0)
+ /* error or EOF in read */
+ return(n);
+ sofar += n;
+ } while (sofar < len);
+ return sofar;
+}
+
diff --git a/lib/erl_interface/test/erl_ext_SUITE.erl b/lib/erl_interface/test/erl_ext_SUITE.erl
new file mode 100644
index 0000000000..dbafea0e39
--- /dev/null
+++ b/lib/erl_interface/test/erl_ext_SUITE.erl
@@ -0,0 +1,81 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_ext_SUITE).
+
+-include("test_server.hrl").
+-include("erl_ext_SUITE_data/ext_test_cases.hrl").
+
+-export([
+ all/1,
+ compare_tuple/1,
+ compare_list/1,
+ compare_string/1,
+ compare_list_string/1,
+ compare_nc_ext/1
+ ]).
+
+-import(runner, [get_term/1]).
+
+all(suite) -> [
+ compare_tuple,
+ compare_list,
+ compare_string,
+ compare_list_string,
+ compare_nc_ext
+ ].
+
+compare_tuple(suite) -> [];
+compare_tuple(doc) -> [];
+compare_tuple(Config) when is_list(Config) ->
+ ?line P = runner:start(?compare_tuple),
+ ?line runner:recv_eot(P),
+ ok.
+
+compare_list(suite) -> [];
+compare_list(doc) -> [];
+compare_list(Config) when is_list(Config) ->
+ ?line P = runner:start(?compare_list),
+ ?line runner:recv_eot(P),
+ ok.
+
+compare_string(suite) -> [];
+compare_string(doc) -> [];
+compare_string(Config) when is_list(Config) ->
+ ?line P = runner:start(?compare_string),
+ ?line runner:recv_eot(P),
+ ok.
+
+compare_list_string(suite) -> [];
+compare_list_string(doc) -> [];
+compare_list_string(Config) when is_list(Config) ->
+ ?line P = runner:start(?compare_list_string),
+ ?line runner:recv_eot(P),
+ ok.
+
+compare_nc_ext(suite) -> [];
+compare_nc_ext(doc) -> [];
+compare_nc_ext(Config) when is_list(Config) ->
+ ?line P = runner:start(?compare_nc_ext),
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..cb7b12cc79
--- /dev/null
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2002-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+ext_test_decl.c: ext_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run ext_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..6f363ccd6f
--- /dev/null
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/Makefile.src
@@ -0,0 +1,41 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2002-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/runner@obj@ \
+ $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+EXT_OBJS = ext_test@obj@ ext_test_decl@obj@
+
+all: ext_test@exe@
+
+clean:
+ $(RM) $(EXT_OBJS)
+ $(RM) ext_test@exe@
+
+ext_test@exe@: $(EXT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(EXT_OBJS) $(LIBFLAGS)
diff --git a/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
new file mode 100644
index 0000000000..ba1a6c66da
--- /dev/null
+++ b/lib/erl_interface/test/erl_ext_SUITE_data/ext_test.c
@@ -0,0 +1,485 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2002-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ *
+
+ */
+/*
+ * Author: Rickard Green
+ * Modified: Bj�rn-Egil Dahlberg
+ * - compare_tuple
+ * - compare_string
+ * - compare_list
+ * - compare_list and string
+ */
+
+#include "runner.h"
+#include "erl_interface.h"
+#include <stdio.h>
+#include <string.h>
+
+typedef unsigned int uint;
+
+#define MAX_NC_EXT_SIZE 100
+
+static unsigned char *
+write_pid(unsigned char *buf, char *node, uint cre, uint ser, uint num);
+static unsigned char *
+write_port(unsigned char *buf, char *node, uint cre, uint id);
+static unsigned char *
+write_ref(unsigned char *buf, char *node, uint cre, uint id[], uint no_ids);
+static void
+test_compare_ext(char *test_desc,
+ unsigned char *ext1,
+ unsigned char *end_ext1,
+ unsigned char *ext2,
+ unsigned char *end_ext2,
+ int exp_res);
+
+/*
+ * Test erl_compare_ext with tuples
+ */
+TESTCASE(compare_tuple) {
+ // erlang:term_to_binary ({'b'})
+ unsigned char term1[] = { 131, 104, 1, 100, 0, 1, 98 };
+ // erlang:term_to_binary ({'a', 'a'})
+ unsigned char term2[] = { 131, 104, 2, 100, 0, 1, 97, 100, 0, 1, 97 };
+ unsigned char *start_a, *start_b, *end_a, *end_b;
+
+ erl_init(NULL, 0);
+ start_a = term1;
+ start_b = term2;
+ end_a = term1 + 7;
+ end_b = term2 + 11;
+
+ test_compare_ext("tuples", start_a, end_a, start_b, end_b, -1);
+
+ report(1);
+}
+
+/*
+ * Test erl_compare_ext with lists
+ */
+
+TESTCASE(compare_list) {
+ unsigned char *start_a, *start_b, *end_a, *end_b;
+ // erlang:term_to_binary([a,b,[],3412])
+ unsigned char term1[] = {131,108,0,0,0,4,100,0,1,97,100,0,1,98,106,98,0,0,13,84,106};
+ // erlang:term_to_binary([34,{a,n},a,erlang])
+ unsigned char term2[] = {131,108,0,0,0,4,97,34,104,2,100,0,1,97,100,0,1,110,100,0,1,97,100,0,6,101,114,108,97,110,103,106};
+
+ erl_init(NULL, 0);
+ start_a = term1;
+ start_b = term2;
+ end_a = term1 + 21;
+ end_b = term2 + 32;
+
+ test_compare_ext("lists", start_a, end_a, start_b, end_b, 1);
+
+ report(1);
+}
+
+/*
+ * Test erl_compare_ext with strings
+ */
+
+TESTCASE(compare_string) {
+ unsigned char *start_a, *start_b, *end_a, *end_b;
+ // erlang:term_to_binary("hej")
+ unsigned char term1[] = {131,107,0,3,104,101,106};
+ // erlang:term_to_binary("erlang")
+ unsigned char term2[] = {131,107,0,6,101,114,108,97,110,103};
+
+ erl_init(NULL, 0);
+ start_a = term1;
+ start_b = term2;
+ end_a = term1 + 7;
+ end_b = term2 + 10;
+
+ test_compare_ext("strings", start_a, end_a, start_b, end_b, 1);
+
+ report(1);
+}
+
+/*
+ * Test erl_compare_ext with lists and strings
+ */
+
+TESTCASE(compare_list_string) {
+ unsigned char *start_a, *start_b, *end_a, *end_b;
+ // erlang:term_to_binary("hej")
+ unsigned char term1[] = {131,107,0,3,104,101,106};
+ // erlang:term_to_binary([a,b,[],3412])
+ unsigned char term2[] = {131,108,0,0,0,4,100,0,1,97,100,0,1,98,106,98,0,0,13,84,106};
+
+ erl_init(NULL, 0);
+ start_a = term1;
+ start_b = term2;
+ end_a = term1 + 7;
+ end_b = term2 + 21;
+
+ test_compare_ext("strings", start_a, end_a, start_b, end_b, -1);
+
+ report(1);
+}
+
+
+
+/*
+ * Test erl_compare_ext with node containers
+ */
+TESTCASE(compare_nc_ext)
+{
+ int res;
+ unsigned char buf_a[MAX_NC_EXT_SIZE], buf_b[MAX_NC_EXT_SIZE];
+ unsigned char *end_a, *end_b;
+ uint id[3];
+
+ erl_init(NULL, 0);
+
+
+ /*
+ * Test pids ----------------------------------------------------
+ *
+ * Significance (most -> least):
+ * nodename, creation, serial, number, nodename, creation
+ *
+ */
+
+ end_a = write_pid(buf_a, "b@b", 2, 4711, 1);
+
+ end_b = write_pid(buf_b, "a@b", 1, 4710, 2);
+ test_compare_ext("pid test 1", buf_a, end_a, buf_b, end_b, -1);
+
+ end_b = write_pid(buf_b, "a@b", 1, 4712, 1);
+ test_compare_ext("pid test 2", buf_a, end_a, buf_b, end_b, -1);
+
+ end_b = write_pid(buf_b, "c@b", 1, 4711, 1);
+ test_compare_ext("pid test 3", buf_a, end_a, buf_b, end_b, -1);
+
+ end_b = write_pid(buf_b, "b@b", 3, 4711, 1);
+ test_compare_ext("pid test 4", buf_a, end_a, buf_b, end_b, -1);
+
+ end_b = write_pid(buf_b, "b@b", 2, 4711, 1);
+ test_compare_ext("pid test 5", buf_a, end_a, buf_b, end_b, 0);
+
+
+ /*
+ * Test ports ---------------------------------------------------
+ *
+ * Significance (most -> least):
+ * nodename, creation, number
+ *
+ * OBS: Comparison between ports has changed in R9. This
+ * since it wasn't stable in R8 (and eariler releases).
+ * Significance used to be: dist_slot, number,
+ * creation.
+ */
+
+ end_a = write_port(buf_a, "b@b", 2, 4711),
+
+ end_b = write_port(buf_b, "c@b", 1, 4710);
+ test_compare_ext("port test 1", buf_a, end_a, buf_b, end_b, -1);
+
+ end_b = write_port(buf_b, "b@b", 3, 4710);
+ test_compare_ext("port test 2", buf_a, end_a, buf_b, end_b, -1);
+
+ end_b = write_port(buf_b, "b@b", 2, 4712);
+ test_compare_ext("port test 3", buf_a, end_a, buf_b, end_b, -1);
+
+ end_b = write_port(buf_b, "b@b", 2, 4711);
+ test_compare_ext("port test 4", buf_a, end_a, buf_b, end_b, 0);
+
+ /*
+ * Test refs ----------------------------------------------------
+ * Significance (most -> least):
+ * nodename, creation, (number high, number mid), number low,
+ *
+ * OBS: Comparison between refs has changed in R9. This
+ * since it wasn't stable in R8 (and eariler releases).
+ * Significance used to be: dist_slot, number,
+ * creation.
+ *
+ */
+
+ /* Long & Long */
+
+ id[0] = 4711; id[1] = 4711, id[2] = 4711;
+ end_a = write_ref(buf_a, "b@b", 2, id, 3);
+
+
+ id[0] = 4710; id[1] = 4710; id[2] = 4710;
+ end_b = write_ref(buf_b, "c@b", 1, id, 3);
+ test_compare_ext("ref test 1", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4710; id[1] = 4710; id[2] = 4710;
+ end_b = write_ref(buf_b, "b@b", 3, id, 3);
+ test_compare_ext("ref test 2", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4710; id[1] = 4710; id[2] = 4712;
+ end_b = write_ref(buf_b, "b@b", 2, id, 3);
+ test_compare_ext("ref test 3", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4710; id[1] = 4712; id[2] = 4711;
+ end_b = write_ref(buf_b, "b@b", 2, id, 3);
+ test_compare_ext("ref test 4", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4712; id[1] = 4711; id[2] = 4711;
+ end_b = write_ref(buf_b, "b@b", 2, id, 3);
+ test_compare_ext("ref test 5", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4711; id[1] = 4711; id[2] = 4711;
+ end_b = write_ref(buf_b, "b@b", 2, id, 3);
+ test_compare_ext("ref test 6", buf_a, end_a, buf_b, end_b, 0);
+
+ /* Long & Short */
+ id[0] = 4711; id[1] = 0, id[2] = 0;
+ end_a = write_ref(buf_a, "b@b", 2, id, 3);
+
+
+ id[0] = 4710;
+ end_b = write_ref(buf_b, "c@b", 1, id, 1);
+ test_compare_ext("ref test 7", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4710;
+ end_b = write_ref(buf_b, "b@b", 3, id, 1);
+ test_compare_ext("ref test 8", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4712;
+ end_b = write_ref(buf_b, "b@b", 2, id, 1);
+ test_compare_ext("ref test 9", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4711;
+ end_b = write_ref(buf_b, "b@b", 2, id, 1);
+ test_compare_ext("ref test 10", buf_a, end_a, buf_b, end_b, 0);
+
+ /* Short & Long */
+ id[0] = 4711;
+ end_a = write_ref(buf_a, "b@b", 2, id, 1);
+
+
+ id[0] = 4710; id[1] = 0, id[2] = 0;
+ end_b = write_ref(buf_b, "c@b", 1, id, 3);
+ test_compare_ext("ref test 11", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4710; id[1] = 0, id[2] = 0;
+ end_b = write_ref(buf_b, "b@b", 3, id, 3);
+ test_compare_ext("ref test 12", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4712; id[1] = 0, id[2] = 0;
+ end_b = write_ref(buf_b, "b@b", 2, id, 3);
+ test_compare_ext("ref test 13", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4711; id[1] = 0, id[2] = 0;
+ end_b = write_ref(buf_b, "b@b", 2, id, 3);
+ test_compare_ext("ref test 14", buf_a, end_a, buf_b, end_b, 0);
+
+ /* Short & Short */
+ id[0] = 4711;
+ end_a = write_ref(buf_a, "b@b", 2, id, 1);
+
+
+ id[0] = 4710;
+ end_b = write_ref(buf_b, "c@b", 1, id, 1);
+ test_compare_ext("ref test 15", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4710;
+ end_b = write_ref(buf_b, "b@b", 3, id, 1);
+ test_compare_ext("ref test 16", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4712;
+ end_b = write_ref(buf_b, "b@b", 2, id, 1);
+ test_compare_ext("ref test 17", buf_a, end_a, buf_b, end_b, -1);
+
+ id[0] = 4711;
+ end_b = write_ref(buf_b, "b@b", 2, id, 1);
+ test_compare_ext("ref test 18", buf_a, end_a, buf_b, end_b, 0);
+
+ report(1);
+}
+
+static void
+test_compare_ext(char *test_desc,
+ unsigned char *ext1,
+ unsigned char *end_ext1,
+ unsigned char *ext2,
+ unsigned char *end_ext2,
+ int exp_res)
+{
+ int er, ar;
+ unsigned char *e1, *e2;
+ int reversed_args;
+ char ext_str[MAX_NC_EXT_SIZE*4 + 1];
+ char *es;
+
+ message("*** %s ***", test_desc);
+ message(" erl_compare_ext() arguments:", test_desc);
+
+ es = &ext_str[0];
+
+ e1 = ext1;
+ while (e1 < end_ext1)
+ es += sprintf(es, "%d,", *(e1++));
+ *(--es) = '\0';
+ message(" e1 = <<%s>>", ext_str);
+
+
+ es = &ext_str[0];
+
+ e2 = ext2;
+ while (e2 < end_ext2)
+ es += sprintf(es, "%d,", *(e2++));
+ *(--es) = '\0';
+ message(" e2 = <<%s>>", ext_str);
+
+ message("Starting %s...", test_desc);
+
+
+ reversed_args = 0;
+ er = exp_res;
+ e1 = ext1;
+ e2 = ext2;
+
+ reversed_args_start:
+
+ ar = erl_compare_ext(e1, e2);
+ if (er < 0) {
+ if (ar > 0)
+ fail("expected result e1 < e2; actual result e1 > e2\n");
+ else if (ar == 0)
+ fail("expected result e1 < e2; actual result e1 = e2\n");
+ }
+ else if (er > 0) {
+ if (ar < 0)
+ fail("expected result e1 > e2; actual result e1 < e2\n");
+ else if (ar == 0)
+ fail("expected result e1 > e2; actual result e1 = e2\n");
+ }
+ else {
+ if (ar > 0)
+ fail("expected result e1 = e2; actual result e1 > e2\n");
+ else if (ar < 0)
+ fail("expected result e1 = e2; actual result e1 < e2\n");
+ }
+
+ message("%s", "SUCCEEDED!");
+ if (!reversed_args) {
+ message("Starting %s with reversed arguments...", test_desc);
+ e2 = ext1;
+ e1 = ext2;
+ if (exp_res < 0)
+ er = 1;
+ else if (exp_res > 0)
+ er = -1;
+ reversed_args = 1;
+ goto reversed_args_start;
+ }
+
+ message("%s", "");
+
+}
+
+
+#define ATOM_EXT (100)
+#define REFERENCE_EXT (101)
+#define PORT_EXT (102)
+#define PID_EXT (103)
+#define NEW_REFERENCE_EXT (114)
+
+
+#define PUT_UINT16(E, X) ((E)[0] = ((X) >> 8) & 0xff, \
+ (E)[1] = (X) & 0xff)
+
+#define PUT_UINT32(E, X) ((E)[0] = ((X) >> 24) & 0xff, \
+ (E)[1] = ((X) >> 16) & 0xff, \
+ (E)[2] = ((X) >> 8) & 0xff, \
+ (E)[3] = (X) & 0xff)
+
+static unsigned char *
+write_atom(unsigned char *buf, char *atom)
+{
+ uint len;
+
+ len = 0;
+ while(atom[len]) {
+ buf[len + 3] = atom[len];
+ len++;
+ }
+ buf[0] = ATOM_EXT;
+ PUT_UINT16(&buf[1], len);
+
+ return buf + 3 + len;
+}
+
+static unsigned char *
+write_pid(unsigned char *buf, char *node, uint cre, uint num, uint ser)
+{
+ unsigned char *e = buf;
+
+ *(e++) = PID_EXT;
+ e = write_atom(e, node);
+ PUT_UINT32(e, num & ((1 << 15) - 1));
+ e += 4;
+ PUT_UINT32(e, ser & ((1 << 3) - 1));
+ e += 4;
+ *(e++) = cre & ((1 << 2) - 1);
+
+ return e;
+}
+
+static unsigned char *
+write_port(unsigned char *buf, char *node, uint cre, uint id)
+{
+ unsigned char *e = buf;
+
+ *(e++) = PORT_EXT;
+ e = write_atom(e, node);
+ PUT_UINT32(e, id & ((1 << 15) - 1));
+ e += 4;
+ *(e++) = cre & ((1 << 2) - 1);
+
+ return e;
+}
+
+static unsigned char *
+write_ref(unsigned char *buf, char *node, uint cre, uint id[], uint no_ids)
+{
+ int i;
+ unsigned char *e = buf;
+
+ if (no_ids == 1) {
+ *(e++) = REFERENCE_EXT;
+ e = write_atom(e, node);
+ PUT_UINT32(e, id[0] & ((1 << 15) - 1));
+ e += 4;
+ *(e++) = cre & ((1 << 2) - 1);
+ }
+ else {
+ *(e++) = NEW_REFERENCE_EXT;
+ PUT_UINT16(e, no_ids);
+ e += 2;
+ e = write_atom(e, node);
+ *(e++) = cre & ((1 << 2) - 1);
+ for (i = 0; i < no_ids; i++) {
+ PUT_UINT32(e, id[i]);
+ e += 4;
+ }
+ }
+
+ return e;
+}
+
diff --git a/lib/erl_interface/test/erl_format_SUITE.erl b/lib/erl_interface/test/erl_format_SUITE.erl
new file mode 100644
index 0000000000..81a0bca80f
--- /dev/null
+++ b/lib/erl_interface/test/erl_format_SUITE.erl
@@ -0,0 +1,136 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_format_SUITE).
+
+-include("test_server.hrl").
+-include("erl_format_SUITE_data/format_test_cases.hrl").
+
+-export([all/1, atoms/1, tuples/1, lists/1]).
+
+-import(runner, [get_term/1]).
+
+%% This test suite test the erl_format() function.
+%% It uses the port program "format_test".
+
+all(suite) -> [atoms, tuples, lists].
+
+%% Tests formatting various atoms.
+
+atoms(suite) -> [];
+atoms(Config) when is_list(Config) ->
+ ?line P = runner:start(?atoms),
+
+ ?line {term, ''} = get_term(P),
+ ?line {term, 'a'} = get_term(P),
+ ?line {term, 'A'} = get_term(P),
+ ?line {term, 'abc'} = get_term(P),
+ ?line {term, 'Abc'} = get_term(P),
+ ?line {term, 'ab@c'} = get_term(P),
+ ?line {term, 'The rain in Spain stays mainly in the plains'} =
+ get_term(P),
+
+ ?line {term, a} = get_term(P),
+ ?line {term, ab} = get_term(P),
+ ?line {term, abc} = get_term(P),
+ ?line {term, ab@c} = get_term(P),
+ ?line {term, abcdefghijklmnopq} = get_term(P),
+
+ ?line {term, ''} = get_term(P),
+ ?line {term, 'a'} = get_term(P),
+ ?line {term, 'A'} = get_term(P),
+ ?line {term, 'abc'} = get_term(P),
+ ?line {term, 'Abc'} = get_term(P),
+ ?line {term, 'ab@c'} = get_term(P),
+ ?line {term, 'The rain in Spain stays mainly in the plains'} =
+ get_term(P),
+
+ ?line {term, a} = get_term(P),
+ ?line {term, ab} = get_term(P),
+ ?line {term, abc} = get_term(P),
+ ?line {term, ab@c} = get_term(P),
+ ?line {term, ' abcdefghijklmnopq '} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+%% Tests formatting various tuples
+
+tuples(suite) -> [];
+tuples(Config) when is_list(Config) ->
+ ?line P = runner:start(?tuples),
+
+ ?line {term, {}} = get_term(P),
+ ?line {term, {a}} = get_term(P),
+ ?line {term, {a, b}} = get_term(P),
+ ?line {term, {a, b, c}} = get_term(P),
+ ?line {term, {1}} = get_term(P),
+ ?line {term, {[]}} = get_term(P),
+ ?line {term, {[], []}} = get_term(P),
+ ?line {term, {[], a, b, c}} = get_term(P),
+ ?line {term, {[], a, [], b, c}} = get_term(P),
+ ?line {term, {[], a, '', b, c}} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
+%% Tests formatting various lists
+
+lists(suite) -> [];
+lists(Config) when is_list(Config) ->
+ ?line P = runner:start(?lists),
+
+ ?line {term, []} = get_term(P),
+ ?line {term, [a]} = get_term(P),
+ ?line {term, [a, b]} = get_term(P),
+ ?line {term, [a, b, c]} = get_term(P),
+ ?line {term, [1]} = get_term(P),
+ ?line {term, [[]]} = get_term(P),
+ ?line {term, [[], []]} = get_term(P),
+ ?line {term, [[], a, b, c]} = get_term(P),
+ ?line {term, [[], a, [], b, c]} = get_term(P),
+ ?line {term, [[], a, '', b, c]} = get_term(P),
+
+ ?line {term, [{name, 'Madonna'}, {age, 21}, {data, [{addr, "E-street", 42}]}]} =
+ get_term(P),
+ case os:type() of
+ vxworks ->
+ ?line {term, [{pi, _}, {'cos(70)', _}]} = get_term(P),
+ ?line {term, [[pi, _], ['cos(70)', _]]} = get_term(P),
+ ?line {term, [[pi, _], [], ["cos(70)", _]]} =
+ get_term(P);
+ _ ->
+ ?line {term, [{pi, 3.1415}, {'cos(70)', 0.34202}]} = get_term(P),
+ ?line {term, [[pi, 3.1415], ['cos(70)', 0.34202]]} = get_term(P),
+ ?line {term, [[pi, 3.1415], [], ["cos(70)", 0.34202]]} =
+ get_term(P)
+ end,
+
+ ?line {term, [-1]} = get_term(P),
+
+ ?line runner:recv_eot(P),
+ ok.
+
+
+
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..2cd313a324
--- /dev/null
+++ b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+format_test_decl.c: format_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run format_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..0cd1ab512d
--- /dev/null
+++ b/lib/erl_interface/test/erl_format_SUITE_data/Makefile.src
@@ -0,0 +1,43 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/runner@obj@ \
+ $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+FORMAT_OBJS = format_test@obj@ format_test_decl@obj@
+
+all: format_test@exe@
+
+clean:
+ $(RM) $(FORMAT_OBJS)
+ $(RM) format_test@exe@
+
+format_test@exe@: $(FORMAT_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(FORMAT_OBJS) $(LIBFLAGS)
+
+
diff --git a/lib/erl_interface/test/erl_format_SUITE_data/format_test.c b/lib/erl_interface/test/erl_format_SUITE_data/format_test.c
new file mode 100644
index 0000000000..75e73b6df5
--- /dev/null
+++ b/lib/erl_interface/test/erl_format_SUITE_data/format_test.c
@@ -0,0 +1,132 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include "runner.h"
+
+/*
+ * Purpose: Tests the erl_format() function.
+ * Author: Bjorn Gustavsson
+ */
+
+static void
+send_format(char* format)
+{
+ send_term(erl_format(format));
+}
+
+TESTCASE(atoms)
+{
+ erl_init(NULL, 0);
+
+ send_format("''");
+ send_format("'a'");
+ send_format("'A'");
+ send_format("'abc'");
+ send_format("'Abc'");
+ send_format("'ab@c'");
+ send_format("'The rain in Spain stays mainly in the plains'");
+
+ send_format("a");
+ send_format("ab");
+ send_format("abc");
+ send_format("ab@c");
+ send_format(" abcdefghijklmnopq ");
+
+ send_term(erl_format("~a", ""));
+ send_term(erl_format("~a", "a"));
+ send_term(erl_format("~a", "A"));
+ send_term(erl_format("~a", "abc"));
+ send_term(erl_format("~a", "Abc"));
+ send_term(erl_format("~a", "ab@c"));
+ send_term(erl_format("~a", "The rain in Spain stays mainly in the plains"));
+
+ send_term(erl_format("~a", "a"));
+ send_term(erl_format("~a", "ab"));
+ send_term(erl_format("~a", "abc"));
+ send_term(erl_format("~a","ab@c"));
+ send_term(erl_format("~a", " abcdefghijklmnopq "));
+
+
+ report(1);
+}
+
+TESTCASE(tuples)
+{
+ erl_init(NULL, 0);
+
+ send_format("{}");
+ send_format("{a}");
+ send_format("{a, b}");
+ send_format("{a, b, c}");
+ send_format("{1}");
+ send_format("{[]}");
+ send_format("{[], []}");
+ send_format("{[], a, b, c}");
+ send_format("{[], a, [], b, c}");
+ send_format("{[], a, '', b, c}");
+
+ report(1);
+}
+
+
+
+TESTCASE(lists)
+{
+ ETERM* a;
+ ETERM* b;
+ ETERM* c;
+
+ erl_init(NULL, 0);
+
+ send_format("[]");
+ send_format("[a]");
+ send_format("[a, b]");
+ send_format("[a, b, c]");
+ send_format("[1]");
+ send_format("[[]]");
+ send_format("[[], []]");
+ send_format("[[], a, b, c]");
+ send_format("[[], a, [], b, c]");
+ send_format("[[], a, '', b, c]");
+
+ b = erl_format("[{addr, ~s, ~i}]", "E-street", 42);
+ a = erl_format("[{name, ~a}, {age, ~i}, {data, ~w}]", "Madonna", 21, b);
+ send_term(a);
+ erl_free_term(b);
+
+ send_term(erl_format("[{pi, ~f}, {'cos(70)', ~f}]", 3.1415, 0.34202));
+
+ a = erl_mk_float(3.1415);
+ b = erl_mk_float(0.34202);
+ send_term(erl_format("[[pi, ~w], ['cos(70)', ~w]]", a, b));
+ erl_free_term(a);
+ erl_free_term(b);
+
+ a = erl_mk_float(3.1415);
+ b = erl_mk_float(0.34202);
+ c = erl_mk_empty_list();
+ send_term(erl_format("[[~a, ~w], ~w, [~s, ~w]]", "pi", a, c, "cos(70)", b));
+ erl_free_term(a);
+ erl_free_term(b);
+ erl_free_term(c);
+
+ send_term(erl_format("[~i]", -1));
+
+ report(1);
+}
diff --git a/lib/erl_interface/test/erl_interface.dynspec b/lib/erl_interface/test/erl_interface.dynspec
new file mode 100644
index 0000000000..8af5040d97
--- /dev/null
+++ b/lib/erl_interface/test/erl_interface.dynspec
@@ -0,0 +1,18 @@
+%% -*- erlang -*-
+%% You can test this file using this command.
+%% file:script("erl_interface.dynspec", [{'TestCCompiler',{msc | gnuc, undefined}}]).
+
+case {TestCCompiler, erlang:system_info(c_compiler_used)} of
+ {{CC, _}, {CC, _}} ->
+ [];
+ {{CC1, _}, {CC2, _}} when CC1 == msc; CC2 == msc ->
+ Comment =
+ "OTP's static C libraries (compiled with "
+ ++ atom_to_list(CC2) ++ ") aren't compatible "
+ "with the C compiler (" ++ atom_to_list(CC1)
+ ++ ") used for testing.",
+ StaticLibSuites = [all_SUITE],
+ lists:map(fun (Suite) -> {skip,{Suite, Comment}} end, StaticLibSuites);
+ {{CC1, _}, {CC2, _}} ->
+ []
+end.
diff --git a/lib/erl_interface/test/erl_interface.spec b/lib/erl_interface/test/erl_interface.spec
new file mode 100644
index 0000000000..2789bd3e2c
--- /dev/null
+++ b/lib/erl_interface/test/erl_interface.spec
@@ -0,0 +1,2 @@
+{topcase, {dir, "../erl_interface_test"}}.
+
diff --git a/lib/erl_interface/test/erl_interface.spec.vxworks b/lib/erl_interface/test/erl_interface.spec.vxworks
new file mode 100644
index 0000000000..7089b3d447
--- /dev/null
+++ b/lib/erl_interface/test/erl_interface.spec.vxworks
@@ -0,0 +1,5 @@
+{topcase, {dir, "../erl_interface_test"}}.
+{skip,{ei_accept_SUITE, ei_threaded_accept,
+ "Threaded test not yet implemented - FIXME"}}.
+{skip,{ei_connect_SUITE, ei_threaded_send,
+ "Threaded test not yet implemented - FIXME"}}.
diff --git a/lib/erl_interface/test/erl_match_SUITE.erl b/lib/erl_interface/test/erl_match_SUITE.erl
new file mode 100644
index 0000000000..f506638544
--- /dev/null
+++ b/lib/erl_interface/test/erl_match_SUITE.erl
@@ -0,0 +1,288 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(erl_match_SUITE).
+
+-include("test_server.hrl").
+-include("erl_match_SUITE_data/match_test_cases.hrl").
+
+-export([all/1, atoms/1, lists/1, tuples/1, references/1, pids/1, ports/1,
+ bind/1, integers/1, floats/1, binaries/1, strings/1]).
+
+%% For interactive running of matcher.
+-export([start_matcher/0, erl_match/3]).
+
+%% This test suite tests the erl_match() function.
+
+all(suite) -> [atoms, lists, tuples, references, pids, ports, bind,
+ integers, floats, binaries, strings].
+
+atoms(suite) -> [];
+atoms(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+
+ ?line eq(P, '', ''),
+ ?line eq(P, a, a),
+ ?line ne(P, a, b),
+ ?line ne(P, a, aa),
+ ?line eq(P, kalle, kalle),
+ ?line ne(P, kalle, arne),
+
+ ?line ne(P, kalle, 42),
+ ?line ne(P, 42, kalle),
+
+ ?line runner:finish(P),
+ ok.
+
+lists(suite) -> [];
+lists(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+ ?line eq(P, [], []),
+
+ ?line ne(P, [], [a]),
+ ?line ne(P, [a], []),
+
+ ?line eq(P, [a], [a]),
+ ?line ne(P, [a], [b]),
+
+ ?line eq(P, [a|b], [a|b]),
+ ?line ne(P, [a|b], [a|x]),
+
+ ?line eq(P, [a, b], [a, b]),
+ ?line ne(P, [a, b], [a, x]),
+
+ ?line eq(P, [a, b, c], [a, b, c]),
+ ?line ne(P, [a, b|c], [a, b|x]),
+ ?line ne(P, [a, b, c], [a, b, x]),
+ ?line ne(P, [a, b|c], [a, b|x]),
+ ?line ne(P, [a, x|c], [a, b|c]),
+ ?line ne(P, [a, b, c], [a, x, c]),
+
+ ?line runner:finish(P),
+ ok.
+
+tuples(suite) -> [];
+tuples(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+
+ ?line ne(P, {}, {a, b}),
+ ?line ne(P, {a, b}, {}),
+ ?line ne(P, {a}, {a, b}),
+ ?line ne(P, {a, b}, {a}),
+
+ ?line eq(P, {}, {}),
+
+ ?line eq(P, {a}, {a}),
+ ?line ne(P, {a}, {b}),
+
+ ?line eq(P, {1}, {1}),
+ ?line ne(P, {1}, {2}),
+
+ ?line eq(P, {a, b}, {a, b}),
+ ?line ne(P, {x, b}, {a, b}),
+
+ ?line ne(P, {error, x}, {error, y}),
+ ?line ne(P, {error, {undefined, {subscriber, last}}},
+ {error, {undefined, {subscriber, name}}}),
+
+ ?line runner:finish(P),
+ ok.
+
+
+references(suite) -> [];
+references(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+ ?line Ref1 = make_ref(),
+ ?line Ref2 = make_ref(),
+
+ ?line eq(P, Ref1, Ref1),
+ ?line eq(P, Ref2, Ref2),
+ ?line ne(P, Ref1, Ref2),
+ ?line ne(P, Ref2, Ref1),
+
+ ?line runner:finish(P),
+ ok.
+
+
+pids(suite) -> [];
+pids(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+ ?line Pid1 = c:pid(0,1,2),
+ ?line Pid2 = c:pid(0,1,3),
+
+ ?line eq(P, self(), self()),
+ ?line eq(P, Pid1, Pid1),
+ ?line ne(P, Pid1, self()),
+ ?line ne(P, Pid2, Pid1),
+
+ ?line runner:finish(P),
+ ok.
+
+
+ports(suite) -> [];
+ports(Config) when is_list(Config) ->
+ case os:type() of
+ vxworks ->
+ {skipped,"not on vxworks, pucko"};
+ _ ->
+ ?line P = start_matcher(),
+ ?line P2 = start_matcher(),
+
+ ?line eq(P, P, P),
+ ?line ne(P, P, P2),
+
+ ?line runner:finish(P),
+ ?line runner:finish(P2),
+ ok
+ end.
+
+integers(suite) -> [];
+integers(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+ ?line I1 = 123,
+ ?line I2 = 12345,
+ ?line I3 = -123,
+ ?line I4 = 2234,
+
+ ?line eq(P, I1, I1),
+ ?line eq(P, I2, I2),
+ ?line ne(P, I1, I2),
+ ?line ne(P, I1, I3),
+ ?line eq(P, I4, I4),
+
+ ?line runner:finish(P),
+ ok.
+
+
+
+floats(suite) -> [];
+floats(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+ ?line F1 = 3.1414,
+ ?line F2 = 3.1415,
+ ?line F3 = 3.1416,
+
+ ?line S1 = "string",
+ ?line S2 = "string2",
+
+ ?line eq(P, F1, F1),
+ ?line eq(P, F2, F2),
+ ?line ne(P, F1, F2),
+ ?line ne(P, F3, F2),
+
+ ?line eq(P, S2, S2),
+ ?line ne(P, S1, S2),
+
+ ?line runner:finish(P),
+ ok.
+
+
+
+binaries(suite) -> [];
+binaries(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+ ?line Bin1 = term_to_binary({kalle, 146015, {kungsgatan, 23}}),
+ ?line Bin2 = term_to_binary(sune),
+ ?line Bin3 = list_to_binary("sune"),
+
+ ?line eq(P, Bin1, Bin1),
+ ?line eq(P, Bin2, Bin2),
+ ?line eq(P, Bin3, Bin3),
+ ?line ne(P, Bin1, Bin2),
+ ?line ne(P, Bin1, Bin3),
+ ?line ne(P, Bin2, Bin3),
+
+ ?line runner:finish(P),
+ ok.
+
+
+
+strings(suite) -> [];
+strings(Config) when is_list(Config) ->
+ ?line P = start_matcher(),
+
+ ?line S1 = "string",
+ ?line S2 = "streng",
+ ?line S3 = "String",
+
+ ?line eq(P, S1, S1),
+ ?line ne(P, S1, S2),
+ ?line ne(P, S1, S3),
+
+ ?line runner:finish(P),
+ ok.
+
+
+
+bind(suite) -> [];
+bind(Config) when is_list(Config) ->
+ ?line P = start_bind(),
+ ?line S = "[X,Y,Z]",
+ ?line L1 = [301,302,302],
+ ?line L2 = [65,66,67],
+
+ ?line bind_ok(P, S, L1),
+ ?line bind_ok(P, S, L2),
+
+ ?line runner:finish(P),
+ ok.
+
+start_bind() ->
+ runner:start(?erl_match_bind).
+
+bind_ok(Port, Bind, Term) ->
+ true = erl_bind(Port, Bind, Term).
+
+%bind_nok(Port, Bind, Term) ->
+% false = erl_bind(Port, Bind, Term).
+
+erl_bind(Port, Pattern, Term) ->
+ Port ! {self(), {command, [$b, Pattern, 0]}},
+ runner:send_term(Port, Term),
+ case runner:get_term(Port) of
+ {term, 0} -> false;
+ {term, 1} -> true
+ end.
+
+
+
+
+
+
+start_matcher() ->
+ runner:start(?erl_match_server).
+
+eq(Port, Pattern, Term) ->
+ true = erl_match(Port, Pattern, Term).
+
+ne(Port, Pattern, Term) ->
+ false = erl_match(Port, Pattern, Term).
+
+
+
+erl_match(Port, Pattern, Term) ->
+ runner:send_term(Port, Pattern),
+ runner:send_term(Port, Term),
+ case runner:get_term(Port) of
+ {term, 0} -> false;
+ {term, 1} -> true
+ end.
+
+
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first
new file mode 100644
index 0000000000..12141d210c
--- /dev/null
+++ b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.first
@@ -0,0 +1,21 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2000-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+match_test_decl.c: match_test.c
+ erl -noinput -pa ../all_SUITE_data -s init_tc run match_test -s erlang halt
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..8ce6c9c985
--- /dev/null
+++ b/lib/erl_interface/test/erl_match_SUITE_data/Makefile.src
@@ -0,0 +1,42 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib@
+LIBEI = $(LIBPATH)/@erl_interface_eilib@
+LIBFLAGS = ../all_SUITE_data/runner@obj@ \
+ $(LIBERL) $(LIBEI) @LIBS@ @erl_interface_sock_libs@ \
+ @erl_interface_threadlib@
+CFLAGS = @EI_CFLAGS@ $(THR_DEFS) -I@erl_interface_include@ -I../all_SUITE_data
+MATCH_OBJS = match_test@obj@ match_test_decl@obj@
+
+all: match_test@exe@
+
+clean:
+ $(RM) $(MATCH_OBJS)
+ $(RM) match_test@exe@
+
+match_test@exe@: $(MATCH_OBJS) $(LIBERL) $(LIBEI)
+ $(LD) @CROSSLDFLAGS@ -o $@ $(MATCH_OBJS) $(LIBFLAGS)
+
diff --git a/lib/erl_interface/test/erl_match_SUITE_data/match_test.c b/lib/erl_interface/test/erl_match_SUITE_data/match_test.c
new file mode 100644
index 0000000000..153a528b0b
--- /dev/null
+++ b/lib/erl_interface/test/erl_match_SUITE_data/match_test.c
@@ -0,0 +1,113 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 1997-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+/*
+ * Purpose: Tests the erl_match() function.
+ * Author: Bjorn Gustavsson
+ */
+
+#include "runner.h"
+
+TESTCASE(erl_match_server)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ ETERM* pattern;
+ ETERM* term;
+
+ pattern = get_term();
+ if (pattern == NULL) {
+ report(1);
+ return;
+ } else {
+ term = get_term();
+ if (term == NULL) {
+ fail("Unexpected EOF term");
+ } else {
+ send_term(erl_mk_int(erl_match(pattern, term)));
+ erl_free_term(pattern);
+ erl_free_term(term);
+ }
+ }
+ }
+
+}
+
+TESTCASE(erl_match_bind)
+{
+ erl_init(NULL, 0);
+
+ for (;;) {
+ char* pattern;
+ ETERM* term;
+
+ pattern=read_packet(NULL);
+
+ switch (pattern[0]) {
+ case 'e':
+ free(pattern);
+ report(1);
+ return;
+
+ case 'b':
+ {
+ ETERM* patt_term;
+
+ /*
+ * Get the pattern string and convert it using erl_format().
+ *
+ * Note that the call to get_term() below destroys the buffer
+ * that the pattern variable points to. Therefore, it is
+ * essential to call erl_format() here, before
+ * calling get_term().
+ */
+
+ message("Pattern: %s", pattern+1);
+ patt_term = erl_format(pattern+1);
+ free(pattern);
+
+ if (patt_term == NULL) {
+ fail("erl_format() failed");
+ }
+
+ /*
+ * Get the term and send back the result of the erl_match()
+ * call.
+ */
+
+ term = get_term();
+ if (term == NULL) {
+ fail("Unexpected eof term");
+ }
+ else {
+ send_term(erl_mk_int(erl_match(patt_term, term)));
+ }
+ erl_free_term(patt_term);
+ erl_free_term(term);
+ }
+ break;
+
+ default:
+ free(pattern);
+ fail("Illegal character received");
+ }
+
+ }
+}
diff --git a/lib/erl_interface/test/port_call_SUITE.erl b/lib/erl_interface/test/port_call_SUITE.erl
new file mode 100644
index 0000000000..895e29ad2e
--- /dev/null
+++ b/lib/erl_interface/test/port_call_SUITE.erl
@@ -0,0 +1,106 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(port_call_SUITE).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% Checks if the dynamic driver and linker loader works.
+%%%
+%%% These tests can only be run installed (outside clearcase).
+%%%
+%%% XXX In this suite is missing test cases for reference counts
+%%% and that drivers are unloaded when their processes die.
+%%% (For me to add :-)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+-export([all/1, basic/1]).
+% Private exports
+-include("test_server.hrl").
+
+
+all(suite) ->
+ [basic].
+
+basic(suite) -> [];
+basic(Config) when is_list(Config) ->
+ case os:type() of
+ {unix, sunos} ->
+ do_basic(Config);
+ {win32,_} ->
+ do_basic(Config);
+ _ ->
+ {skipped, "Dynamic linking and erl_interface not fully examined"
+ " on this platform..."}
+ end.
+
+do_basic(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(10)),
+ ?line Path = ?config(data_dir, Config),
+
+ ?line erl_ddll:start(),
+
+ %% Load the echo driver and verify that it was loaded.
+ {ok,L1,L2}=load_port_call_driver(Path),
+
+ %% Verify that the driver works.
+
+ ?line Port = open_port({spawn, port_call_drv}, [eof]),
+ ?line {hej, "hopp",4711,123445567436543653} =
+ erlang:port_call(Port,{hej, "hopp",4711,123445567436543653}),
+ ?line {hej, "hopp",4711,123445567436543653} =
+ erlang:port_call(Port,0,{hej, "hopp",4711,123445567436543653}),
+ ?line {[], a, [], b, c} =
+ erlang:port_call(Port,1,{hej, "hopp",4711,123445567436543653}),
+ ?line {return, {[], a, [], b, c}} =
+ erlang:port_call(Port,2,{[], a, [], b, c}),
+ ?line List = lists:duplicate(200,5),
+ ?line {return, List} = erlang:port_call(Port,2,List),
+ ?line {'EXIT',{badarg,_}} = (catch erlang:port_call(Port,4711,[])),
+ ?line {'EXIT',{badarg,_}} = (catch erlang:port_call(sune,2,[])),
+ ?line register(gunnar,Port),
+ ?line {return, List} = erlang:port_call(gunnar,2,List),
+ ?line {return, a} = erlang:port_call(gunnar,2,a),
+ ?line erlang:port_close(Port),
+ %% Unload the driver and verify that it was unloaded.
+ ok=unload_port_call_driver(L1,L2),
+
+ ?line {error, {already_started, _}} = erl_ddll:start(),
+ ?line ok = erl_ddll:stop(),
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+load_port_call_driver(Path) ->
+ ?line {ok, L1} = erl_ddll:loaded_drivers(),
+ ?line ok = erl_ddll:load_driver(Path, port_call_drv),
+ ?line {ok, L2} = erl_ddll:loaded_drivers(),
+ ?line ["port_call_drv"] = ordsets:to_list(ordsets:subtract(ordsets:from_list(L2),
+ ordsets:from_list(L1))),
+ {ok,L1,L2}.
+
+unload_port_call_driver(L1,L2) ->
+ ?line {ok, L2} = erl_ddll:loaded_drivers(),
+ ?line ok = erl_ddll:unload_driver(port_call_drv),
+ ?line {ok, L3} = erl_ddll:loaded_drivers(),
+ ?line [] = ordsets:to_list(ordsets:subtract(ordsets:from_list(L3),
+ ordsets:from_list(L1))),
+ ok.
+
diff --git a/lib/erl_interface/test/port_call_SUITE_data/Makefile.src b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..dc7385ba32
--- /dev/null
+++ b/lib/erl_interface/test/port_call_SUITE_data/Makefile.src
@@ -0,0 +1,39 @@
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2001-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
+
+include @erl_interface_mk_include@@[email protected]
+
+CC0 = @CC@
+CC = ..@DS@all_SUITE_data@DS@gccifier@exe@ -CC"$(CC0)"
+LD = @LD@
+LIBPATH = @erl_interface_libpath@
+LIBERL = $(LIBPATH)/@erl_interface_lib_drv@
+LIBEI = $(LIBPATH)/@erl_interface_eilib_drv@
+
+SHLIB_EXTRA_LDLIBS = $(LIBERL) $(LIBEI)
+SHLIB_EXTRA_CFLAGS = -I@erl_interface_include@ -I../all_SUITE_data
+
+
+all: port_call_drv@dll@
+
+clean:
+ $(RM) port_call_drv@obj@
+ $(RM) port_call_drv@dll@
+
+@SHLIB_RULES@
diff --git a/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c b/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
new file mode 100644
index 0000000000..80811fb973
--- /dev/null
+++ b/lib/erl_interface/test/port_call_SUITE_data/port_call_drv.c
@@ -0,0 +1,103 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2001-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#include <stdio.h>
+#include "erl_interface.h"
+#include "erl_driver.h"
+
+static ErlDrvPort my_erlang_port;
+static ErlDrvData echo_start(ErlDrvPort, char *);
+static void from_erlang(ErlDrvData, char*, int);
+static int do_call(ErlDrvData drv_data, unsigned int command, char *buf,
+ int len, char **rbuf, int rlen, unsigned *ret_flags);
+static ErlDrvEntry echo_driver_entry = {
+ NULL, /* Init */
+ echo_start,
+ NULL, /* Stop */
+ from_erlang,
+ NULL, /* Ready input */
+ NULL, /* Ready output */
+ "port_call_drv",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ do_call
+};
+
+DRIVER_INIT(echo_drv)
+{
+ return &echo_driver_entry;
+}
+
+static ErlDrvData
+echo_start(ErlDrvPort port, char *buf)
+{
+ return (ErlDrvData) port;
+}
+
+static void
+from_erlang(ErlDrvData data, char *buf, int count)
+{
+ driver_output((ErlDrvPort) data, buf, count);
+}
+
+static int
+do_call(ErlDrvData drv_data, unsigned int command, char *buf,
+ int len, char **rbuf, int rlen, unsigned *ret_flags)
+{
+ int nlen;
+ ei_x_buff x;
+
+ switch (command) {
+ case 0:
+ *rbuf = buf;
+ *ret_flags |= DRIVER_CALL_KEEP_BUFFER;
+ return len;
+ case 1:
+ ei_x_new(&x);
+ ei_x_format(&x, "{[], a, [], b, c}");
+ nlen = x.index;
+ if (nlen > rlen) {
+ *rbuf =driver_alloc(nlen);
+ }
+ memcpy(*rbuf,x.buff,nlen);
+ ei_x_free(&x);
+ return nlen;
+ case 2:
+ ei_x_new(&x);
+ ei_x_encode_version(&x);
+ ei_x_encode_tuple_header(&x,2);
+ ei_x_encode_atom(&x,"return");
+ ei_x_append_buf(&x,buf+1,len-1);
+ nlen = x.index;
+ if (nlen > rlen) {
+ *rbuf =driver_alloc(nlen);
+ }
+ memcpy(*rbuf,x.buff,nlen);
+ ei_x_free(&x);
+ return nlen;
+ default:
+ return -1;
+ }
+}
+
diff --git a/lib/erl_interface/test/runner.erl b/lib/erl_interface/test/runner.erl
new file mode 100644
index 0000000000..b72723c6a5
--- /dev/null
+++ b/lib/erl_interface/test/runner.erl
@@ -0,0 +1,130 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+-module(runner).
+
+-export([test/1, test/2,
+ start/1, send_term/2, finish/1, send_eot/1, recv_eot/1,
+ get_term/1, get_term/2]).
+
+-define(default_timeout, test_server:seconds(5)).
+
+%% Executes a test case in a C program.
+%%
+%% This function is useful for test cases written in C which requires
+%% no further input, and only returns a result by calling report().
+
+test(Tc) ->
+ test(Tc, ?default_timeout).
+
+test(Tc, Timeout) ->
+ Port = start(Tc),
+
+ case get_term(Port, Timeout) of
+ eot ->
+ ok;
+ Other ->
+ io:format("In this test case, a success/failure result was"),
+ io:format("expected from the C program.\n"),
+ io:format("Received: ~p", [Other]),
+ test_server:fail()
+ end.
+
+%% Executes a test case in a C program. Returns the port.
+%%
+%% Use get_term/1,2.
+%%
+%% Returns: {ok, Port}
+
+start({Prog, Tc}) when is_list(Prog), is_integer(Tc) ->
+ Port = open_port({spawn, Prog}, [{packet, 4}]),
+ Command = [Tc div 256, Tc rem 256],
+ Port ! {self(), {command, Command}},
+ Port.
+
+%% Finishes a test case by send an 'eot' message to the C program
+%% and waiting for an 'eot'.
+%%
+%% If the C program doesn't require an 'eot', use recv_eot/1 instead.
+
+finish(Port) when is_port(Port) ->
+ send_eot(Port),
+ recv_eot(Port).
+
+%% Sends an Erlang term to a C program.
+
+send_term(Port, Term) when is_port(Port) ->
+ Port ! {self(), {command, [$t, term_to_binary(Term)]}}.
+
+%% Sends an 'eot' (end-of-test) indication to a C progrm.
+
+send_eot(Port) when is_port(Port) ->
+ Port ! {self(), {command, [$e]}}.
+
+%% Waits for an 'eot' indication from the C program.
+%% Either returns 'ok' or invokes test_server:fail().
+
+recv_eot(Port) when is_port(Port) ->
+ case get_term(Port) of
+ eot ->
+ ok;
+ Other ->
+ io:format("Error finishing test case. Expected eof from"),
+ io:format("C program, but got:"),
+ io:format("~p", [Other]),
+ test_server:fail()
+ end.
+
+%% Reads a term from the C program.
+%%
+%% Returns: {term, Term}|eot|'NULL' or calls test_server:fail/1,2.
+
+get_term(Port) ->
+ get_term(Port, ?default_timeout).
+
+get_term(Port, Timeout) ->
+ case get_reply(Port, Timeout) of
+ [$b|Bytes] ->
+ {bytes, Bytes};
+ [$f] ->
+ test_server:fail();
+ [$f|Reason] ->
+ test_server:fail(Reason);
+ [$t|Term] ->
+ {term, binary_to_term(list_to_binary(Term))};
+ [$N] ->
+ 'NULL';
+ [$e] ->
+ eot;
+ [$m|Message] ->
+ io:format("~s", [Message]),
+ get_term(Port, Timeout);
+ Other ->
+ io:format("Garbage received from C program: ~p", [Other]),
+ test_server:fail("Illegal response from C program")
+ end.
+
+get_reply(Port, Timeout) when is_port(Port) ->
+ receive
+ {Port, {data, Reply}} ->
+ Reply
+ after Timeout ->
+ test_server:fail("No response from C program")
+ end.
diff --git a/lib/ic/doc/src/Makefile b/lib/ic/doc/src/Makefile
index f00bba2c71..26d0932a95 100644
--- a/lib/ic/doc/src/Makefile
+++ b/lib/ic/doc/src/Makefile
@@ -73,6 +73,9 @@ XML_CHAPTER_FILES = \
BOOK_FILES = book.xml
+XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
+ $(XML_PART_FILES) $(XML_CHAPTER_FILES)
+
GIF_FILES = \
book.gif \
notes.gif \
diff --git a/lib/ic/doc/src/c-part.xml b/lib/ic/doc/src/c-part.xml
index 91c81c8ef3..cef4399960 100644
--- a/lib/ic/doc/src/c-part.xml
+++ b/lib/ic/doc/src/c-part.xml
@@ -4,23 +4,21 @@
<part>
<header>
<copyright>
- <year>2002</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>2002</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
</legalnotice>
<title>IDL to C language Mapping</title>
diff --git a/lib/ic/doc/src/ch_c_corba_env.xml b/lib/ic/doc/src/ch_c_corba_env.xml
index 557eeffdd4..bd4b52ca34 100644
--- a/lib/ic/doc/src/ch_c_corba_env.xml
+++ b/lib/ic/doc/src/ch_c_corba_env.xml
@@ -281,7 +281,7 @@ typedef struct {
<p>By using the <em>CORBA_Environment_alloc</em>/2 function. </p>
<p>The CORBA_Environment_alloc function is defined as:</p>
<code type="none">
-\\011 CORBA_Environment *CORBA_Environment_alloc(int inbufsz,
+ CORBA_Environment *CORBA_Environment_alloc(int inbufsz,
int outbufsz);
</code>
<p>where:</p>
diff --git a/lib/ic/doc/src/ch_c_mapping.xml b/lib/ic/doc/src/ch_c_mapping.xml
index 58b026ee78..f5a921bfd2 100644
--- a/lib/ic/doc/src/ch_c_mapping.xml
+++ b/lib/ic/doc/src/ch_c_mapping.xml
@@ -770,24 +770,24 @@ CORBA_Environment* oe_env)
<p>While the <c>erlang::binary</c> idl type has the same C-definition as
a generated sequence of octets :</p>
<code type="none"><![CDATA[
-\011 module erlang
-\011 {
+ module erlang
+ {
-\011 ....
+ ....
-\011 // an erlang binary
-\011 typedef sequence<octet> binary;
-\011
-\011 };
+ // an erlang binary
+ typedef sequence<octet> binary;
+
+ };
]]></code>
<p>it provides a way on sending trasparent data between C and Erlang.</p>
<p>The C-definition (ic.h) for an erlang binary is :</p>
<code type="none">
-\011 typedef struct {
-\011 CORBA_unsigned_long _maximum;
-\011 CORBA_unsigned_long _length;
-\011 CORBA_octet* _buffer;
-\011 } erlang_binary; /* ERLANG BINARY */
+ typedef struct {
+ CORBA_unsigned_long _maximum;
+ CORBA_unsigned_long _length;
+ CORBA_octet* _buffer;
+ } erlang_binary; /* ERLANG BINARY */
</code>
<p>The differences (between <c>erlang::binary</c> and <c><![CDATA[sequence< octet >]]></c>) are :</p>
<list type="bulleted">
diff --git a/lib/ic/doc/src/ch_erl_genserv.xml b/lib/ic/doc/src/ch_erl_genserv.xml
index 972eff7c17..055b751ba1 100644
--- a/lib/ic/doc/src/ch_erl_genserv.xml
+++ b/lib/ic/doc/src/ch_erl_genserv.xml
@@ -168,18 +168,18 @@ handle_info(Info, State) ->
%% IDL specification
produce(State) ->
case catch random:uniform() of
-\\011{'EXIT',_} ->
-\\011 {stop, normal, "random:uniform/0 - EXIT", State};
-\\011RUnif ->
+ {'EXIT',_} ->
+ {stop, normal, "random:uniform/0 - EXIT", State};
+ RUnif ->
{reply, RUnif, State}
end.
init(State, S1, S2, S3) ->
case catch random:seed(S1, S2, S3) of
-\\011{'EXIT',_} ->
-\\011 {stop, normal, State};
-\\011_ ->
+ {'EXIT',_} ->
+ {stop, normal, State};
+ _ ->
{noreply, State}
end.
</code>
diff --git a/lib/ic/doc/src/ch_erl_plain.xml b/lib/ic/doc/src/ch_erl_plain.xml
index 36de46f624..1d6f84b5ea 100644
--- a/lib/ic/doc/src/ch_erl_plain.xml
+++ b/lib/ic/doc/src/ch_erl_plain.xml
@@ -75,7 +75,7 @@
<item>
<p>Main file : "plain.idl"</p>
<code type="none">
-\011
+
module rmod {
interface random {
diff --git a/lib/ic/doc/src/ch_ic_protocol.xml b/lib/ic/doc/src/ch_ic_protocol.xml
index 678fdc766c..68a01a6a46 100644
--- a/lib/ic/doc/src/ch_ic_protocol.xml
+++ b/lib/ic/doc/src/ch_ic_protocol.xml
@@ -69,9 +69,9 @@
<title>IDL Operations</title>
<p>An IDL operation is declared as follows:</p>
<code type="none">
-\011[oneway] RetType Op(in IType1 I1, in IType2 I2, ..., in ITypeN IN,
-\011out OType1 O1, out OType2 O2, ..., out OTypeM OM)
-\011N, M = 0, 1, 2, ...\011\011(2.1.1)
+ [oneway] RetType Op(in IType1 I1, in IType2 I2, ..., in ITypeN IN,
+ out OType1 O1, out OType2 O2, ..., out OTypeM OM)
+ N, M = 0, 1, 2, ... (2.1.1)
</code>
<p>`Op' is the operation name, RetType is the return type, and ITypei,
i = 1, 2, ..., N, and OTypej, j = 1, 2, ..., M, are the `in' types
@@ -146,13 +146,13 @@
<section>
<title>Call (Request/Reply, i.e. not oneway)</title>
<code type="none">
- request:\011\011 Op\011\011\011atom()\011\011N = 0\011
-\011\011\011 {Op, I1, I2, ..., IN}\011tuple()\011\011N > 0
-\011\011\011\011\011\011\011\011(3.1.1)
+ request: Op atom() N = 0
+ {Op, I1, I2, ..., IN} tuple() N > 0
+ (3.1.1)
- reply:\011\011 Ret\011\011\011\011\011M = 0
-\011\011\011 {Ret, O1, O2, ..., OM}\011\011\011M > 0
-\011\011\011\011\011\011\011\011(3.1.2) </code>
+ reply: Ret M = 0
+ {Ret, O1, O2, ..., OM} M > 0
+ (3.1.2)</code>
<p><em>Notice:</em> Even if the RetType of the operation Op is
declared to be 'void', a return value 'ok' is returned in
the reply message. That
@@ -166,9 +166,9 @@
<title>Cast (oneway)</title>
<code type="none">
- notification:\011Op\011\011\011atom()\011\011N = 0
-\011\011\011{Op, I1, I2, ..., IN}\011tuple()\011\011N > 0
-\011\011\011\011\011\011\011\011(3.2.1) </code>
+ notification: Op atom() N = 0
+ {Op, I1, I2, ..., IN} tuple() N > 0
+ (3.2.1)</code>
<p>(There is of course no return message).
</p>
</section>
@@ -184,9 +184,9 @@
<title>Call</title>
<code type="none">
- request:\011{'$gen_call', {self(), Ref}, Request}\011\011(4.1.1)
+ request: {'$gen_call', {self(), Ref}, Request} (4.1.1)
- reply:\011{Ref, Reply}\011\011\011\011\011(4.1.2) </code>
+ reply: {Ref, Reply} (4.1.2)</code>
<p>where Request and Reply are the messages defined in the previous
chapter.
</p>
@@ -195,7 +195,7 @@
<section>
<title>Cast</title>
<code type="none">
- notification: {'$gen_cast', Notification}\011\011(4.2.1) </code>
+ notification: {'$gen_cast', Notification} (4.2.1) </code>
<p>where Notification is the message defined in the previous chapter.
</p>
</section>
@@ -205,7 +205,7 @@
<title>Erlang Distribution Protocol</title>
<p>Messages (of interest here) between Erlang nodes are of the form: </p>
<code type="none">
- Len(4), Type(1), CtrlBin(N), MsgBin(M)\011\011\011(5.1) </code>
+ Len(4), Type(1), CtrlBin(N), MsgBin(M) (5.1) </code>
<p>Type is equal to 112 = PASS_THROUGH.
</p>
<p>CtrlBin and MsgBin are Erlang terms in binary form (as if created
@@ -215,10 +215,10 @@
<p>CtrlBin (of interest here) contains the SEND and REG_SEND control
messages, which are binary forms of the Erlang terms</p>
<code type="none">
-\011{2, Cookie, ToPid} ,\011\011\011\011\011(5.2) </code>
+ {2, Cookie, ToPid} , (5.2) </code>
<p>and</p>
<code type="none">
-\011{6, FromPid, Cookie, ToName} ,\011\011\011\011(5.3) </code>
+ {6, FromPid, Cookie, ToName} , (5.3) </code>
<p>respectively.
</p>
<p>The CtrlBin(N) message is read and written by erl_interface code
diff --git a/lib/ic/doc/src/ch_java.xml b/lib/ic/doc/src/ch_java.xml
index 831850f211..a189daa44b 100644
--- a/lib/ic/doc/src/ch_java.xml
+++ b/lib/ic/doc/src/ch_java.xml
@@ -711,14 +711,14 @@ public class sHelper {
// methods
public static s unmarshal(OtpInputStream in)
throws java.lang.Exception {
-\011:
-\011:
+ :
+ :
};
public static void marshal(OtpOutputStream out, s value)
throws java.lang.Exception {
-\011:
-\011:
+ :
+ :
};
};
diff --git a/lib/ic/doc/src/erl-part.xml b/lib/ic/doc/src/erl-part.xml
index b5041dce7f..8dd7001436 100644
--- a/lib/ic/doc/src/erl-part.xml
+++ b/lib/ic/doc/src/erl-part.xml
@@ -4,23 +4,21 @@
<part>
<header>
<copyright>
- <year>2002</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>2002</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
</legalnotice>
<title>IDL to Erlang language Mapping</title>
diff --git a/lib/ic/doc/src/ic_c_protocol.xml b/lib/ic/doc/src/ic_c_protocol.xml
index f895fe0723..26862addf9 100644
--- a/lib/ic/doc/src/ic_c_protocol.xml
+++ b/lib/ic/doc/src/ic_c_protocol.xml
@@ -4,23 +4,21 @@
<cref>
<header>
<copyright>
- <year>2004</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>2004</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
</legalnotice>
<title>IC C Protocol Functions</title>
diff --git a/lib/ic/doc/src/java-part.xml b/lib/ic/doc/src/java-part.xml
index 69cc0f026c..ab4049ee2a 100644
--- a/lib/ic/doc/src/java-part.xml
+++ b/lib/ic/doc/src/java-part.xml
@@ -4,23 +4,21 @@
<part>
<header>
<copyright>
- <year>2002</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>2002</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
</legalnotice>
<title>IDL to Java language Mapping</title>
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index 021a1e058f..dbafde7b4b 100644
--- a/lib/ic/doc/src/notes.xml
+++ b/lib/ic/doc/src/notes.xml
@@ -37,9 +37,21 @@
<title>Fixed Bugs and Malfunctions</title>
<list type="bulleted">
<item>
+ <p>Removed superfluous VT in the documentation.</p>
+ <p>Own id: OTP-8353 Aux Id:</p>
+ </item>
+ <item>
<p>The option c_timeout was not correctly documented.</p>
<p>Own id: OTP-8307 Aux Id: seq11390</p>
</item>
+ <item>
+ <p>Removed superfluous backslash in the documentation.</p>
+ <p>Own id: OTP-8354 Aux Id:</p>
+ </item>
+ <item>
+ <p>The documentation EIX file was not generated.</p>
+ <p>Own id: OTP-8355 Aux Id:</p>
+ </item>
</list>
</section>
</section>
diff --git a/lib/ic/doc/src/old_notes.xml b/lib/ic/doc/src/old_notes.xml
deleted file mode 100644
index 9ba0262573..0000000000
--- a/lib/ic/doc/src/old_notes.xml
+++ /dev/null
@@ -1,1565 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2003</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>IDL Compiler Release Notes</title>
- <prepared></prepared>
- <docno></docno>
- <checked></checked>
- <date>2003-11-19</date>
- <rev>AB</rev>
- </header>
-
- <section>
- <title>IC 4.1.8</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>IDL-files containing <c>result</c> or <c>Result</c> as,
- for example, parameter name, caused an exit with reason
- <c>bad_match</c>.</p>
- <p>Own Id: OTP-4532</p>
- </item>
- <item>
- <p>Uninitialized variables were used in <c>ic_init_ref</c> for
- C backends. </p>
- <p>Own Id: OTP-4537 <br></br>
-
- Aux Id: seq7666, ETOtr17107</p>
- </item>
- <item>
- <p><c>CORBA_Environment_alloc()</c> left some fields
- uninitialized in the returned pointer to an
- <c>CORBA_Environment</c> for C backends.</p>
- <p>Own Id: OTP-4538</p>
- </item>
- <item>
- <p>The function <c>ic_compare_refs()</c> for C backends
- could find two unequal references to be equal.</p>
- <p>Own Id: OTP-4539</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.7</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Operation names were always scoped in C server backend,
- irrespective of the setting of the option
- <c>scoped_op_calls</c>.</p>
- <p>Own Id: OTP-4521 <br></br>
-
- Aux Id: seq7643, ETOtr16925</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.6</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>For C backends generated code checks that the
- <c>_length</c> field of bounded sequences (i.e. specified
- as <c><![CDATA[sequence <TYPE, MAX>]]></c>) does not exceed the
- specified maximum length. If so, an exception is raised.</p>
- <p>Own Id: OTP-4471</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The <c>_maximum</c> field was not set for sequence structs
- generated by the C backends.</p>
- <p>Own Id: OTP-4471 <br></br>
-
- Aux Id: seq7600, ETOtr16308</p>
- </item>
- <item>
- <p>There was a memory leak in C backends in case there was a
- decoding error in a sequence with elements of basic type.</p>
- <p>Own Id: OTP-4475</p>
- </item>
- <item>
- <p>For for C backends, IDL structs defined within an
- interface were not mapped into C structs in appropriate
- include files.</p>
- <p>Own Id: OTP-4481 <br></br>
-
- Aux Id: seq7617</p>
- </item>
- <item>
- <p>If the user, incorrectly, trap exit's but did not use the
- 'handle_info' compile option it would cause the server to
- terminate. The same problem occurred if someone,
- illegally, sent a message to the server. It could also
- happen for illegal oneway operations.</p>
- <p>Own Id: OTP-4488</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Invalid C code was generated for type short. </p>
- <p>Own Id: OTP-4450 <br></br>
-
- Aux Id: seq7582</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.4</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Operation functions inherited by an interface were not
- placed in the map table in generated code for the C server
- backend. As a result such functions were not found by the
- switch function of the interface.</p>
- <p>Own Id: OTP-4448 <br></br>
-
- Aux Id: seq7582</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.3.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A non-ANSI compliant construct in libic.a was changed.</p>
- <p>Own Id: -</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>For Erlang and C back-ends an IC version stamp has been
- added to generated source code. This stamp i preserved in
- compiled target code.</p>
- </item>
- <item>
- <p>For C backends an <c>assert()</c> expression has been
- added to generated code. That expression asserts that the
- result of a memory allocation size calculation is strictly
- positive. An error will result in a printout and an
- <c>abort()</c>. The assertion can be inhibited by defining
- the macro <c>NDEBUG</c> (according to ANSI C).</p>
- <p>If the assertion is inhibited, and a size calculation error
- is detected, an INTERNAL CORBA exception is set. </p>
- </item>
- <item>
- <p>An internal reorganization of C backend generator code has
- been done (addition of module <c>ic_cclient</c>). Several
- changes has been done in generated C code:</p>
- <list type="bulleted">
- <item>
- <p>The typedef <c>___generic___</c> has been replaced by
- the typedef <c>___exec_function___</c>, which has been
- made more strict; for backward compatibility the
- <c>___generic___</c> typedef is now an alias for
- <c>___exec_function___</c>.</p>
- </item>
- <item>
- <p>Function parameters that are arrays, has been changed
- to be pointers to array slices, which are equivalent
- according to ANSI C. </p>
- </item>
- <item>
- <p>The storage class specifier <c>extern</c> has been
- removed from function prototypes in header files.</p>
- </item>
- <item>
- <p>Redundant type casts have been removed from generated code.
- Also some local "generic" variables have been renamed.</p>
- </item>
- </list>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Module info vsn replaced by app_vsn.</p>
- <p>Own Id: OTP-4341</p>
- </item>
- <item>
- <p>IC-4.1.2 disabled the definition of float constants
- beginning with a zero (e.g. <c>0.14</c>).</p>
- <p>Own Id: OTP-4367</p>
- </item>
- <item>
- <p>IC did not handle constant definitions correctly for
- char, string, wchar and wstring.</p>
- <p>Own Id: OTP-4067, OTP-3222</p>
- </item>
- <item>
- <p>IC did not recognize all reserved words defined in the
- OMG specification (2.3.1). The new keywords are <c>fixed, abstract, custom, factory, local, native, private, public, supports, truncatable, 'ValueBase'</c> and
- <c>valuetype</c>. But for now this is only active for the
- <c>erl_corba</c> backend and only incorrect usage of
- <c>fixed</c>, since this datatype is now supported,
- triggers an error for this backend.</p>
- <p>Own Id: OTP-4368</p>
- </item>
- <item>
- <p>It was not possible to use wchar or wstring inside a
- union body when using the Java backend.</p>
- <p>Own Id:
- OTP-4365</p>
- </item>
- <item>
- <p>The compile options <c>this</c> and <c>handle_info</c>
- did not behave as described in the documentation. The
- <c>timeout</c> now behaves as, for example,
- <c>handle_info</c>.</p>
- <p>Own Id: OTP-4386, OTP-3231</p>
- </item>
- <item>
- <p>If we typedef a sequence, which contains a struct or a union,
- the access function <c>id/0</c> returned an incorrect IFR Id
- if a prefix pragma was used.</p>
- <p>Own Id: OTP-4387</p>
- </item>
- <item>
- <p>If an IDL file contained a prefix pragma, incorrect
- IFR-id's was generated in the IFR-registration operation
- <c>oe_register</c> for aliases (typedef) and
- attributes.</p>
- <p>Own Id: OTP-4388, OTP-4392</p>
- </item>
- <item>
- <p>For C back-ends, when encodings/decodings failed, memory
- allocated for variable size parameter types was not freed.</p>
- <p>Own Id: OTP-4391
- <br></br>
-Aux Id: seq7438, ETOtr14009</p>
- </item>
- <item>
- <p>If an IDL file contained a multiple typedef
- (e.g. typedef string str1, str2;), the <c>oe_unregister</c>
- operation failed to remove all data, in this case str2,
- from the IFR.</p>
- <p>Own Id: OTP-4393</p>
- </item>
- <item>
- <p>IC did not recognize octet-constants
- (e.g. const octet octetmax = 255;).</p>
- <p>Own Id: OTP-4400</p>
- </item>
- <item>
- <p>Negative 'long long' constants was not accepted
- (e.g. const long long MyConstant = -1;).</p>
- <p>Own Id: OTP-4401</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.2</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Merging of map's (<em>___map___</em>) using the
- <em>___merge___</em> function does not work.</p>
- <p>Own Id: OTP-4323</p>
- </item>
- <item>
- <p>Error in generated C decode/encode functions for union's with
- discriminator where the union has no value for all discriminator
- values. E.g. a union with discriminator boolean where only the
- discriminator value TRUE has a corresponding union value.
- Here is how such a thing would look in IDL:</p>
- <pre>
-\011 union OptXList switch(boolean) {
-\011 case TRUE: integer val;
- };
- </pre>
- <p>Own Id: OTP-4322</p>
- </item>
- <item>
- <p>Scoped op calls ('{scoped_op_calls, true}') does not handle
- module/function names beginning with capital letter (e.g.
- Megaco should be 'Megaco') for oneway operations (handle_cast).</p>
- <p>Own Id: OTP-4310</p>
- </item>
- <item>
- <p>A bug is fixed on C-IDL erlang binaries that caused
- pointer error when residing inside sequences.</p>
- <p>Own Id: OTP-4303</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.1.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>A new option 'multiple_be' is added that allows multiple backend
- generation for the same IDL file.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed on IDL types that contain underscore '_'.</p>
- <p>Own Id: OTP-3710</p>
- </item>
- <item>
- <p>A bug is fixed on IDL structs that caused scope confusion
- when types and fields of a struct had the same name.</p>
- <p>Own Id: OTP-2893</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0.7</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The Erlang binary special type is introduced, that
- allows efficient transfer of binaries between Erlang and C. </p>
- <p>Own Id:OTP-4107</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0.6</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed on noc backend which caused generation of erroneous code.</p>
- <p>Own Id: OTP-3812</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0.5</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The pragma code option is extended to point
- specific functions on NOC backend, not only
- interfaces.</p>
- <p></p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0.4</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug in pragma prefix when including IDL files is fixed.
- This caused problems for Erlang-corba IFR registrations.</p>
- <p>Own Id: OTP-3620</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Limited support on multiple file module definitions.</p>
- <p>The current version supports multiple file module definitions all
- backends except the c oriented backends.</p>
- <p>Own Id: OTP-3550</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0.2</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed on Erlang backends.</p>
- <p>The (recently) introduced generation of files
- describing sequence and array files were even
- true for included interfaces. In the case of
- some Erlang backends this were unnecessary.</p>
- <p>Own Id: OTP-3485</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>New functionality added on Java and Erl_genserv backends.</p>
- <p></p>
- <list type="bulleted">
- <item>
- <p>On the Java client stub :</p>
- <p></p>
- <list type="bulleted">
- <item>
- <p>The Java client have now one more constructor function,
- that allows to continue with an already started connection.</p>
- </item>
- <item>
- <p><c>void __stop()</c> which sends a stop cast call to the server.
- While this causes the Erlang server to terminate, it
- sets a stop flag to the Java server environment, requesting the
- server to terminate.</p>
- </item>
- <item>
- <p><c>void __reconnect()</c> which closes the current client connection
- if open and then connects to the same server.</p>
- </item>
- </list>
- <p>The Environment variable is now declared as <c>public</c>. </p>
- </item>
- <item>
- <p>On the Java server skeleton :</p>
- <p></p>
- <list type="bulleted">
- <item>
- <p><c>boolean __isStopped()</c> which returns true if a <c>stop</c>
- message where received, false otherwise. The user must check if
- this function returns true, and in this case exit the implemented
- server loop.</p>
- </item>
- </list>
- <p>The Environment variable is now declared as <c>protected</c> which
- allows the implementation that extends the stub to access it.</p>
- </item>
- <item>
- <p>On the Erlang gen_server stub :</p>
- <p></p>
- <list type="bulleted">
- <item>
- <p><c>stop(Server)</c> which yields to a cast call to the standard
- gen_server <c>stop</c> function. This will always terminate the
- Erlang gen_server, while it will set the stop flag for the
- Java server stub.</p>
- </item>
- </list>
- </item>
- </list>
- <p>Own Id: OTP-3433</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 4.0</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>New types handled by IC.</p>
- <p>The following OMG-IDL types are added in this compiler version :</p>
- <list type="bulleted">
- <item>
- <p>long long</p>
- <p>unsigned long long</p>
- <p>wchar</p>
- <p>wstring</p>
- </item>
- </list>
- <p>Own Id: OTP-3331</p>
- <p></p>
- </item>
- <item>
- <p>TypeCode as built in type and access code files for array and sequence types.</p>
- <list type="bulleted">
- <item>
- <p>As TypeCode is a <c>pseudo</c>-interface, it is now is a built-in type on IC.</p>
- </item>
- <item>
- <p>Access code files which contain information about TypeCode, ID and Name are
- now generated for user defined arrays and sequences.</p>
- </item>
- </list>
- <p>Own Id: OTP-3392</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.8.2</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <p>A bug is fixed on preprocessor directive expansion.</p>
- <p>When nested #ifdef - #ifndef directives, a bug caused
- improper included file expansion. This is fixed by
- repairing the preprocessor expansion function.</p>
- <p>Own Id: OTP-3472</p>
- </section>
- </section>
-
- <section>
- <title>IC 3.8.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Build in Erlang types support for java-backends</p>
- <p>The built-in Erlang types <c>term, port, ref</c> and <c>pid</c>
- are needed in Java backends in order to support an
- efficient mapping between the two languages.
- The new types are also supported by additional
- helpers and holders to match with OMGs Java mapping
- As a result of this, the following classes are added to
- the <c>com.ericsson.otp.ic</c> interface :</p>
- <list type="bulleted">
- <item>
- <p><c>Term,TermHelper,TermHolder</c> which represents the
- built-in Erlang type <c>term</c></p>
- </item>
- <item>
- <p><c>Ref,RefHelper,RefHolder</c> which represents the
- built-in Erlang type <c>ref</c></p>
- </item>
- <item>
- <p><c>Port,PortHelper, PortHolder</c> which represents the
- built-in Erlang type <c>port</c></p>
- </item>
- <item><c>Pid, PidHelper and PidHolder</c> which represents the
- built-in Erlang type <c>pid</c></item>
- </list>
- <p></p>
- <p>Own Id: OTP-3348</p>
- <p></p>
- </item>
- <item>
- <p>Compile time preprocessor macro variable definitions</p>
- <p>The preprocessor lacked possibility to accept user
- defined variables other than the one defined in IDL files.
- This limited the use of command-ruled IDL specifications.
- Now the build-in preprocessor allows the user to set variables
- by using the "preproc_flags" option the same way
- as using the "gcc" preprocessor.</p>
- <p>Supported flags : </p>
- <list type="bulleted">
- <item>
- <p><c><![CDATA["-D< Variable >"]]></c> which defines a variable</p>
- </item>
- <item>
- <p><c><![CDATA["-U< Variable >"]]></c> which undefines a variable</p>
- </item>
- </list>
- <p></p>
- <p>Own Id: OTP-3349</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <p>A bug on comment type expansion is fixed.</p>
- <p>The comment type expansion were erroneous when
- inherited types (NOC backend).
- This is now fixed and the type naming agree with
- the scope of the inheritor interface.</p>
- <p>Own Id: OTP-3346</p>
- </section>
- </section>
-
- <section>
- <title>IC 3.8</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The code generated for java backend is optimized
- due to use of streams instead for tuple classes
- when (un)marshalling message calls.
- Support for building clients using asynchronous
- client calls and effective multi-threaded servers.</p>
- <p>Own Id: OTP-3310</p>
- <p></p>
- </item>
- <item>
- <p>The <c>any</c> type is now supported for java backend.</p>
- <p>Own Id: OTP-3311</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>A bug on C generated constants is fixed</title>
- <p>While the constants are evaluated and behave well when used
- inside an IDL specification their C-export were not working properly.
- The constant export definitions were not generated well :</p>
- <list type="bulleted">
- <item>
- <p>the declared C definition were erroneous ( the name did not always agree
- with the scope the constant were declared in ).</p>
- </item>
- <item>
- <p>there were no C- definition generated for the c-server backend when
- the constants were declared inside an interface.</p>
- </item>
- </list>
- <p>Own Id: OTP-3219</p>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <p>Due to optimizations in java backend, the stub initialization and usage
- differs than the previous version.</p>
- <p>Client stub interface changes:</p>
- <list type="bulleted">
- <item>
- <p>Client disconnects by calling the <c>__disconnect()</c> function instead
- for the old <c>_closeConnection()</c></p>
- <p></p>
- </item>
- <item>
- <p>All <c>marshal</c> operation functions have now the interface :</p>
- <p><c><![CDATA[void _< OpName >_marshal(Environment<, Param |, Params >)]]></c></p>
- <p>instead for</p>
- <p><c><![CDATA[OtpErlangTuple _< OpName >_marshal(< Param, | Params, >OtpErlangPid, OtpErlangRef)]]></c></p>
- <p></p>
- </item>
- <item>
- <p>All <c>unmarshal</c> operation functions have now the interface :</p>
- <p><c><![CDATA[< Ret value > _< OpName >_unmarshal(Environment<, Param |, Params >)]]></c></p>
- <p>instead for</p>
- <p><c><![CDATA[< Ret value > _< OpName >_unmarshal(< Param, | Params, >OtpErlangTuple, OtpErlangRef)]]></c></p>
- <p></p>
- </item>
- <item>
- <p>Call reference extraction is available by the client function :</p>
- <p><c>OtpErlangRef __getRef()</c></p>
- <p>instead for previous function :</p>
- <p><c>OtpErlangRef _getReference(OtpErlangTuple)</c></p>
- <p></p>
- </item>
- </list>
- <p>Server skeleton interface changes:</p>
- <list type="bulleted">
- <item>
- <p>The implementation function no longer have to contain the
- two (2) contractor functions (with <c>super()</c>). This is due
- to the fact that there is only one contractor function for each
- skeleton file :</p>
- <p><c><![CDATA[public _< interface name >ImplBase()]]></c></p>
- <p></p>
- </item>
- <item>
- <p>The parameter for the caller identity extraction function <c>_getCallerPid</c>
- is now an <c>Environment</c> variable instead for an <c>OtpErlangTuple</c>.</p>
- <p></p>
- </item>
- <item>
- <p>There is a new <c>invoke</c> function :</p>
- <p><c>OtpOutputStream invoke(OtpInputStream)</c></p>
- <p>instead for the old one :</p>
- <p><c>OtpErlangTuple invoke(OtpErlangTuple)</c></p>
- <p></p>
- </item>
- <item>
- <p>The <c>OtpConnection</c> class function used for receiving messages is now :</p>
- <p><c>OtpInputStream receiveBuf()</c></p>
- <p>instead for the old one :</p>
- <p><c>OtpErlangTuple receive()</c></p>
- <p></p>
- </item>
- <item>
- <p>The <c>OtpConnection</c> class function used for sending messages is now :</p>
- <p><c>void sendBuf(OtpErlangPid, OtpOutputStream)</c></p>
- <p>instead for the old one :</p>
- <p><c>void send(OtpErlangPid, OtpErlangTuple)</c></p>
- <p></p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.7.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <p>Some memory usage optimizations for the compiler were done.</p>
- </section>
-
- <section>
- <title>Fixed bugs and malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed when C backend is used.</p>
- <p>When C-union with enumerant discriminator, the size
- calculation of the discriminator value were erroneous.
- This lead to the side effect that only the first case of the
- union were allowed.
- The error were fixed by fixing the size calculation of
- the discriminator. </p>
- <p>Own Id: OTP-3215</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.7</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed when C backend is used.</p>
- <p>When unions with enumerant discriminator
- were decoded, an error encountered in the
- union size calculation. </p>
- <p>Own Id: OTP-3209</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.6</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed when NOC backend is used.</p>
- <p>When several functions with the same name
- were found in the included file tree,
- a compile time failure occurred.</p>
- <p>Own Id: OTP-3203</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.5</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Noc backend optimization</p>
- <p>When NOC backend is choosen, the type code
- information on the stub functions is reduced
- to a single atom "no_tk".
- This is the default behavior. The typecode
- generation is enabled by the "use_tk" switch.</p>
- <p>Own Id: OTP-3196</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>General java backend bug fixes </p>
- <p>Protocol errors on user defined structures and
- union types are corrected.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.4</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Semantic test enhancements.</p>
- <p>The compiler detects now semantic errors when enumerant
- values collide with user defined types on the same name scope.</p>
- <p>Own Id: OTP-3157 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>General java backend bug-fixes </p>
- <p>Several bugs were fixed on user defined types.</p>
- <list type="bulleted">
- <item>
- <p>Union discriminators work better when
- all possible case values are defined.</p>
- </item>
- <item>
- <p>A bug on Interface inherited operations is
- fixed that cause errors on generated server switch.</p>
- </item>
- <item>
- <p>Type definitions on included files are better generated. </p>
- </item>
- </list>
- <p>Own Id: OTP-3156 <br></br>
-</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>A new back-end which generates Java code according to the CORBA IDL to Java mapping for
- communication with the Erlang distribution protocol has been added to IC.
- For the moment there is no support for the Erlang types Pid, Ref, Port and Term
- but this will be added later.</p>
- <p>Own Id: OTP-2779 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Fixed the bug that the c code backends sometimes generated incorrect code for
- struct arguments. They shall always be pointers. </p>
- <p>Own Id: OTP-2732 <br></br>
-</p>
- </item>
- <item>
- <p>The code generation is fixed so the array parameters now follow the
- CORBA V2.0 C mapping.</p>
- <p>Own Id: OTP-2873 <br></br>
-</p>
- </item>
- <item>
- <p>Fixed the problem that the checking of the numbers of out-parameters always was true.</p>
- <p>Own Id: OTP-2944 <br></br>
-</p>
- </item>
- <item>
- <p>Fixed the bug that some temporary variables was not declared when c code.</p>
- <p>Own Id: OTP-2950 <br></br>
-</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.2.2</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Unions are now supported to agree with OMG's C mapping.</p>
- <p>Own Id: OTP-2868 <br></br>
-</p>
- </item>
- <item>
- <p>There is now a possibility to use pre- and postcondition methods on the server side
- for IC generated Corba Objects. The compiler option is documented in the ic reference manual
- and an example of how the pre- and postcondition methods should be designed and used is
- added to ic example directory (an ReadMe.txt file exists with some instructions for
- running the example code).</p>
- <p>Own Id: OTP-3068 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The compiler ignores unknown/non supported pragma directives. A warning is raised
- while the generated code will then be the same as if the corresponding
- (unknown) pragma directive were missing. </p>
- <p>Own Id: OTP-3052 <br></br>
-</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.2.1</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Wrong C code was generated for limited strings when they where included
- from another IDL specification.</p>
- <p>Own Id: OTP-3033 <br></br>
-</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.2</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The buffers for in/output used by C-stubs are now expandable.
- This fixes buffer overflow problems when messages received/sent
- do not fit in buffers.</p>
- <p>Own Id: OTP-3001 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <p>The CORBA_Environment structure has now two new fields, the buffers for in/output
- must now be dynamically allocated.</p>
- </section>
- </section>
-
- <section>
- <title>IC 3.1.2</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The generated IFR registration function for constants has been fixed
- so the parameters are correct.</p>
- <p>Own Id: OTP-2856 <br></br>
-</p>
- </item>
- <item>
- <p>Error in the C code generation of ONEWAY operations without parameters
- The bug was an decoding error in the operation header. The generated code expected one
- parameter instead of zero. This is now fixed.</p>
- <p>Own Id: OTP-2909 <br></br>
-</p>
- </item>
- <item>
- <p>Type problems on floats and booleans fixed.</p>
- <p>Erroneous code for runtime checks on float was removed and
- the internal format of the data representing the boolean value
- is upgraded.</p>
- <p>Own Id: OTP-2925 <br></br>
-</p>
- </item>
- <item>
- <p>The generated code for arrays of typedefined strings were
- erroneous in the C-backends due to a failure in the compiler internal type
- checking.</p>
- <p>Own Id: OTP-2936 <br></br>
-</p>
- </item>
- <item>
- <p>The generated code for typedefined nested sequences were erroneous
- in the C-backends. Pointer mismatches caused compilation failure.</p>
- <p>Own Id: OTP-2937 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <p>The IDL specifications must be regenerated for C due to changes in the code generation.</p>
- <p>One must regenerate IDL specifications for Erlang CORBA if there are constants in the
- specification due to previous errors in the IFR registration functions (OTP-2856).</p>
- </section>
- </section>
-
- <section>
- <title>IC 3.1.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Improvements on error report on unsupported types by</p>
- <p>propagating warning when declaring unions in C -backends</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed when arrays that contained variable size data
- on C-backends</p>
- <p>The compiler generated erroneous code when IDL
- defined arrays that contained variable size data such
- as strings, variable size structs or sequences.</p>
- <p>Own Id: OTP-2900 <br></br>
-</p>
- </item>
- <item>
- <p>A bug is fixed when sequences that contained variable size data
- on C_backends</p>
- <p>The compiler generated erroneous code when IDL
- defined arrays that contained variable size data such
- as strings, variable size structs or other sequences.</p>
- <p>Own Id: OTP-2901 <br></br>
-</p>
- </item>
- <item>
- <p>A bug concerning bounded strings on C-backends is fixed.</p>
- <p>The compiler generated erroneous code for IDL
- defined bounded strings. Syntax errors were generated
- in special cases of typdedefined strings.</p>
- <p>Own Id: OTP-2898 <br></br>
-</p>
- </item>
- <item>
- <p>A runtime error when sequences that contained integer types is fixed.</p>
- <p>When C-clients/server that communicated with Erlang clients/servers,
- and the data send by Erlang part were a list of small numbers,
- the Erlang runtime compacts the list to a string. This caused a
- runtime error when sending sequences of integer types and all had
- value less than 256.</p>
- <p>Own Id: OTP-2899 <br></br>
-</p>
- </item>
- <item>
- <p>An OMG IDL - C mapping problem on enumerant values is fixed.</p>
- <p>The enumerant values names is now prefixed by the current scope,
- as defined in the specification.</p>
- <p>Own Id: OTP-2902 <br></br>
-</p>
- </item>
- <item>
- <p>A problem when using constants in array declarations is fixed.</p>
- <p>Array dimensions declared with constants generated erroneous code.</p>
- <p>Own Id: OTP-2864 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Changes in C-generation on enumerant values.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.1</title>
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug is fixed on the generated structures. </p>
- <p>The generated C code for the structures corresponds now
- to direct mapping of C-structs. </p>
- <p>Own Id: OTP-2843 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Included structures inside a struct are no longer pointers.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 3.0</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Interface change for C-backends</p>
- <p>Major interface change. The new interface is CORBA 2.0
- compliant.</p>
- <p>Own Id: OTP-2845 <br></br>
-</p>
- </item>
- <item>
- <p>The C-backends functionality is improved</p>
- <list type="bulleted">
- <item>
- <p>Due to interface change and some unneeded error
- checks,the C-generated code is fairly optimized.</p>
- </item>
- </list>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Several serious bugs on decoding and memory allocation are fixed. </p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Interface change on the C-backends</p>
- <p>In order to be CORBA 2.0 compatible, the new version
- generates fully incompatible C code.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 2.5.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>A new backend is added : C-server</p>
- <p>This back-ends can be used to create servers,
- compatible to c-clients, and Erlang genserver clients.
- The code produced is a collection of functions for
- encoding and decoding messages and a switch that coordinates
- them. These parts can be used to create other servers as well.
- All functions are exported to header files.</p>
- <p>Own Id: OTP-2713 <br></br>
-</p>
- </item>
- <item>
- <p>The C-client functionality is improved</p>
- <list type="bulleted">
- <item>
- <p>The static buffer used for input/output is removed along
- with the <c>memset</c> function that initiated it.
- The new client is at least 20-30 percent faster.</p>
- </item>
- <item>
- <p>The internal structure of the client is changed.
- The client functions are now a collection of encoding
- and decoding message functions ruled by a specific
- call function. While the basic client generated is
- a synchronous client, the exported functions
- support the implementation of threaded asynchronous
- clients.</p>
- </item>
- <item>
- <p>The static buffer used for input/output is remove along
- with the <c>memset</c> function that initiated it.
- The new client is at least 20-30 percent faster.</p>
- </item>
- <item>
- <p>The code generated is generally improved, warnings are
- (almost) eliminated, while no unidentified variable
- errors occur.</p>
- </item>
- <item>
- <p>The IDL types unsigned shorts, shorts, floats are supported now.</p>
- </item>
- <item>
- <p>All generated functions are exported in client header files..</p>
- </item>
- </list>
- <p>Own Id: OTP-2712 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Changes in compiler usage and code generation.</title>
- <list type="bulleted">
- <item>
- <p>A new option is added for the C-server back-end : <c>c_server</c>.</p>
- </item>
- <item>
- <p>A new option is added : <c>scoped_op_calls</c>.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A bug oneway operations on erl_corba and erl_genserv that caused
- en exit due to internal interface error is fixed. </p>
- </item>
- <item>
- <p>A bug on oneway operations on c_genserv back-end that caused several
- variables to be unidentified is fixed. </p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Interface change on the C-client</p>
- <p>The client functions are called with two extra variables, a pointer to
- an array of char - used for storage and an integer - the array size</p>
- </item>
- <item>
- <p>The IDL type <c>attribute</c> is disabled, due to some implementation problems.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 2.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The compiler now provides more in depth information (printouts) when errors occur.</p>
- <p>In some cases the compiler stops compiling
- due to an abnormal exit or incompatible input.
- In this situation, a "fatal error" may occur but the compiler will
- generate information explaining the problem.</p>
- <p>Own Id: OTP-2565 <br></br>
-</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>IC 2.0</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The IDL compiler is now a separate application and is longer a part of Orber.</p>
- </item>
- <item>
- <p>Pragma handling implementation.</p>
- <p>Pragma ID, prefix
- and version are implemented to agree with CORBA revision
- 2.0. The compiler accepts and applies these on the
- behavior of the compiled code. <br></br>
- In this implementation,
- pragmas are accepted by the parser and applied by the use
- of ic_pragma functions. <br></br>
- All IFR-identity handling now
- passes through pragma table. As pragma handling in OMG-IDL
- is affecting the identity of an ifr-object, all identity
- handling and registration is now controlled by pragma
- functions. A hash table called "pragmatab" contains vital
- identity information used under compilation. <br></br>
-</p>
- <p>There two major pragma categories :</p>
- <list type="bulleted">
- <item>
- <p>Normal pragmas, are used in the code where
- basic definitions and statements appear. </p>
- </item>
- <item>
- <p>Under certain circumstances, ugly pragmas can now
- appear inside code, parameter lists, structure
- definitions ... etc. <br></br>
- It is quite challenging to
- allow ugly pragmas, but the effects of unlimited ugly
- pragma implementation on the parser can be enormous.
- Ugly pragmas can cause the parser source code to
- become time consuming and user unreadable. <br></br>
- In order
- to allow ugly pragmas but not destroy the current
- structure of the parser, the use of ugly pragmas is
- limited. Multiple pragma directives are allowed
- inside parameter lists, unions, exceptions,
- enumerated type, structures... as long as they are do not
- appear between two keywords or between keywords and
- identifiers. </p>
- </item>
- </list>
- <p>The pragma effect is the same for both scope and basic
- pragma rules. </p>
- <p>When compiling, an IFR-identity
- must be looked up several times but by storing identity aliases inside
- the pragma table there this an increase in both speed and
- flexibility. </p>
- <p>Own Id: OTP-2128 <br></br>
-</p>
- </item>
- <item>
- <p>Code for interface inheritance registration for the IFR
- registration code .</p>
- <p>Inherited interfaces can now
- be registered as a list of interface descriptions by
- entering code for inherited interface registration under
- new interface creation. This is achieved by correcting the
- function reg2/6 and adding two more functions,
- get_base_interfaces/2 and call_fun_str/2 </p>
- <p>Own Id:
- OTP-2134 <br></br>
-</p>
- </item>
- <item>
- <p>IFR registration checks for included IDL files.</p>
- <p>All top level definitions (with respect to the scope) -
- modules, interfaces, constants, types or exceptions - found
- in an IDL file are either defined inside the compiled IDL
- file or inside included files.
- By having an extended registration of all top level
- definitions it becomes possible to simply produce checks
- for those included by the current IDL file.
- A function call include_reg_test/1 is added in all
- OE_* files that checks for IFR-registration on all included
- IDL files. The code for that function is added inside the
- OE_* file, while the function is called under OE_*:OE_register/0
- operation. </p>
- <p>Own Id: OTP-2138 <br></br>
-</p>
- </item>
- <item>
- <p>Exception registration under IFR-operation creation.</p>
- <p>By entering code for exception registration under operation
- creation, the exceptions of an operation can be checked now.
- This is done by correcting the function get_exceptions/4
- and adding two more functions, excdef/5 and get_EXC_ID/5
- ( the last two are cooperating with the first one and
- all three are defined in the module "ictk" ). </p>
- <p>Own Id: OTP-2102 <br></br>
-</p>
- </item>
- <item>
- <p>New back-end to IDL compiler : Plain Erlang.</p>
- <p>The new back-end just translates IDL specifications
- to Erlang module calls. No pragmas are allowed.</p>
- <p>Own Id: OTP-2471 <br></br>
-</p>
- </item>
- <item>
- <p>New back-end to IDL compiler : generic server.</p>
- <p>A new back-end that translates IDL specifications
- to a standard OTP generic server.</p>
- <p>Own Id: OTP-2482 <br></br>
-</p>
- </item>
- <item>
- <p>New back-end to IDL compiler : c client generation</p>
- <p>A new back-end that translates IDL specifications
- to a C API for accessing servers in Erlang. </p>
- <p>Own Id: OTP-1511 <br></br>
-</p>
- </item>
- <item>
- <p>All records in generated files reveal own Erlang modules.</p>
- <p>In Erlang related back-ends, every structure
- which generates definition form is a record,
- (such as union, struct, exception.... ). These records are
- held in a generated Erlang files which
- contain functions that reveal record information. <br></br>
-
- The Erlang file which contain these functions is
- named after the scope of the record (similar
- to the generated module and interface files). <br></br>
-
- Three functions are available :</p>
- <list type="bulleted">
- <item>
- <p>tc/0 - returns the record type code,</p>
- </item>
- <item>
- <p>id/0 - returns the record id,</p>
- </item>
- <item>
- <p>name - returns the record name.</p>
- </item>
- </list>
- <p>Own Id: OTP-2473 <br></br>
-</p>
- </item>
- <item>
- <p>Changes in compiler usage and code generation.</p>
- <list type="bulleted">
- <item>
- <p>New compilation flags.
- New flag be ( = back-end ) which is
- used by the compiler to choose back-end.
- Default back-end is set to erl_corba.</p>
- </item>
- <item>
- <p>Stub files have an extra function oe_dependency/0
- indicating file dependency. This
- helps the user to determine which IDL files should to
- be compiled beside the compiled file. </p>
- </item>
- </list>
- <p>Own Id: OTP-2474 <br></br>
-</p>
- </item>
- <item>
- <p>The IDL generation for CORBA is changed so standard gen_server return values can be used
- from the implementation module. The change is compatible so that old values remain valid.</p>
- <p>Own Id: OTP-2485 <br></br>
-</p>
- </item>
- <item>
- <p>It's now possible to generate an API to a CORBA object that accepts
- timeout values in the calls in the same manner as gen_server.
- The option to the compiler is "timeout".</p>
- <p>Own Id: OTP-2487 <br></br>
-</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Empty file generation problem is fixed.
- When the IDL module definition did not contain
- constant definitions, the generated stub file for that module
- definition was empty. After checking the module body,
- these files will not be generated anymore.</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Changes in generated files.</p>
- <p>Stub-files generated by the compiler had
- prefix "OE_" and those used by Orber
- had also a register/unregister function
- called "OE_register"/"OE_unregister" and
- a directive "OE_get_interface" passed
- to the gen_server.
- This made it difficult/irritating to use,
- for example call to the register function
- in Orber would appear as shown below:</p>
- <list type="bulleted">
- <item>
- <p>'OE_filename':'OE_register'().</p>
- </item>
- </list>
- <p>This is changed by using the prefix "oe_"
- instead for "OE_" for the above.
- A registration call in Orber is now written:</p>
- <list type="bulleted">
- <item>
- <p>oe_filename:oe_register(). </p>
- </item>
- </list>
- <p>Own Id: OTP-2440 <br></br>
-</p>
- </item>
- </list>
- </section>
- </section>
-</chapter>
-
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index ec4bb7c3a6..e0fccf4889 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1,6 +1,9 @@
IC_VSN = 4.2.24
-TICKETS = OTP-8307
+TICKETS = OTP-8307 \
+ OTP-8353 \
+ OTP-8354 \
+ OTP-8355
TICKETS_4.2.23 = OTP-8201
diff --git a/lib/kernel/src/code_server.erl b/lib/kernel/src/code_server.erl
index 018f7f41d2..d4e3f0bcf8 100644
--- a/lib/kernel/src/code_server.erl
+++ b/lib/kernel/src/code_server.erl
@@ -1479,13 +1479,12 @@ finish_on_load(Ref, OnLoadRes, #state{on_load=OnLoad0,moddb=Db}=State) ->
end.
finish_on_load_1(Mod, File, OnLoadRes, WaitingPids, Db) ->
- Keep = if
- is_boolean(OnLoadRes) -> OnLoadRes;
- true -> false
- end,
+ Keep = OnLoadRes =:= ok,
erlang:finish_after_on_load(Mod, Keep),
Res = case Keep of
- false -> {error,on_load_failure};
+ false ->
+ finish_on_load_report(Mod, OnLoadRes),
+ {error,on_load_failure};
true ->
ets:insert(Db, {Mod,File}),
{module,Mod}
@@ -1493,6 +1492,24 @@ finish_on_load_1(Mod, File, OnLoadRes, WaitingPids, Db) ->
[reply(Pid, Res) || Pid <- WaitingPids],
ok.
+finish_on_load_report(_Mod, Atom) when is_atom(Atom) ->
+ %% No error reports for atoms.
+ ok;
+finish_on_load_report(Mod, Term) ->
+ %% Play it very safe here. The error_logger module and
+ %% modules it depend on may not be loaded yet and there
+ %% would be a dead-lock if we called it directly
+ %% from the code_server process.
+ spawn(fun() ->
+ F = "The on_load function for module "
+ "~s returned ~P\n",
+
+ %% Express the call as an apply to simplify
+ %% the ext_mod_dep/1 test case.
+ E = error_logger,
+ E:warning_msg(F, [Mod,Term,10])
+ end).
+
%% -------------------------------------------------------
%% Internal functions.
%% -------------------------------------------------------
diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl
index fc9508a194..cb9fec2ffe 100644
--- a/lib/kernel/src/pg2.erl
+++ b/lib/kernel/src/pg2.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 1997-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(pg2).
@@ -334,8 +334,11 @@ local_group_members(Name) ->
P <- member_in_group(Pid, Name)].
member_in_group(Pid, Name) ->
- [{{member, Name, Pid}, N}] = ets:lookup(pg2_table, {member, Name, Pid}),
- lists:duplicate(N, Pid).
+ case ets:lookup(pg2_table, {member, Name, Pid}) of
+ [] -> [];
+ [{{member, Name, Pid}, N}] ->
+ lists:duplicate(N, Pid)
+ end.
member_groups(Pid) ->
[Name || [Name] <- ets:match(pg2_table, {{pid, Pid, '$1'}})].
diff --git a/lib/kernel/test/code_SUITE.erl b/lib/kernel/test/code_SUITE.erl
index 9fda66711d..38aadac202 100644
--- a/lib/kernel/test/code_SUITE.erl
+++ b/lib/kernel/test/code_SUITE.erl
@@ -31,12 +31,17 @@
where_is_file_cached/1, where_is_file_no_cache/1,
purge_stacktrace/1, mult_lib_roots/1, bad_erl_libs/1,
code_archive/1, code_archive2/1, on_load/1,
- on_load_embedded/1]).
+ on_load_embedded/1, on_load_errors/1]).
-export([init_per_testcase/2, fin_per_testcase/2,
init_per_suite/1, end_per_suite/1,
sticky_compiler/1]).
+%% error_logger
+-export([init/1,
+ handle_event/2, handle_call/2, handle_info/2,
+ terminate/2]).
+
all(suite) ->
[set_path, get_path, add_path, add_paths, del_path,
replace_path, load_file, load_abs, ensure_loaded,
@@ -47,7 +52,8 @@ all(suite) ->
load_cached, start_node_with_cache, add_and_rehash,
where_is_file_no_cache, where_is_file_cached,
purge_stacktrace, mult_lib_roots, bad_erl_libs,
- code_archive, code_archive2, on_load, on_load_embedded].
+ code_archive, code_archive2, on_load, on_load_embedded,
+ on_load_errors].
init_per_suite(Config) ->
%% The compiler will no longer create a Beam file if
@@ -671,6 +677,8 @@ check_funs({'$M_EXPR','$F_EXPR',2},
check_funs({'$M_EXPR','$F_EXPR',1},
[{lists,foreach,2},
{hipe_unified_loader,patch_consts,3} | _]) -> 0;
+check_funs({'$M_EXPR',warning_msg,2},
+ [{code_server,finish_on_load_report,2} | _]) -> 0;
%% This is cheating! /raimo
%%
%% check_funs(This = {M,_,_}, Path) ->
@@ -1229,6 +1237,81 @@ is_source_dir() ->
filename:basename(code:lib_dir(kernel)) =:= "kernel" andalso
filename:basename(code:lib_dir(stdlib)) =:= "stdlib".
+on_load_errors(Config) when is_list(Config) ->
+ Master = on_load_error_test_case_process,
+ ?line register(Master, self()),
+
+ ?line Data = filename:join([?config(data_dir, Config),"on_load_errors"]),
+ ?line ok = file:set_cwd(Data),
+ ?line up_to_date = make:all([{d,'MASTER',Master}]),
+
+ ?line do_on_load_error(an_atom),
+
+ ?line error_logger:add_report_handler(?MODULE, self()),
+
+ ?line do_on_load_error({something,terrible,is,wrong}),
+ receive
+ Any1 ->
+ ?line {_, "The on_load function"++_,
+ [on_load_error,
+ {something,terrible,is,wrong},_]} = Any1
+ end,
+
+ ?line do_on_load_error(fail), %Cause exception.
+ receive
+ Any2 ->
+ ?line {_, "The on_load function"++_,
+ [on_load_error,{failed,[_|_]},_]} = Any2
+ end,
+
+ %% There should be no more messages.
+ receive
+ Unexpected ->
+ ?line ?t:fail({unexpected,Unexpected})
+ after 10 ->
+ ok
+ end,
+
+ ok.
+
+do_on_load_error(ReturnValue) ->
+ ?line {_,Ref} = spawn_monitor(fun() ->
+ exit(on_load_error:main())
+ end),
+ receive {on_load_error,ErrorPid} -> ok end,
+ ?line ErrorPid ! ReturnValue,
+ receive
+ {'DOWN',Ref,process,_,Exit} ->
+ ?line {undef,[{on_load_error,main,[]}|_]} = Exit
+ end.
+
+%%-----------------------------------------------------------------
+%% error_logger handler.
+%% (Copied from stdlib/test/proc_lib_SUITE.erl.)
+%%-----------------------------------------------------------------
+init(Tester) ->
+ {ok, Tester}.
+
+handle_event({error, _GL, {emulator, _, _}}, Tester) ->
+ {ok, Tester};
+handle_event({error, _GL, Msg}, Tester) ->
+ Tester ! Msg,
+ {ok, Tester};
+handle_event(_Event, State) ->
+ {ok, State}.
+
+handle_info(_, State) ->
+ {ok, State}.
+
+handle_call(_Query, State) -> {ok, {error, bad_query}, State}.
+
+terminate(_Reason, State) ->
+ State.
+
+%%%
+%%% Common utility functions.
+%%%
+
start_node(Name, Param) ->
?t:start_node(Name, slave, [{args, Param}]).
diff --git a/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl b/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl
index 660000df46..f6bcb6570b 100644
--- a/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl
+++ b/lib/kernel/test/code_SUITE_data/on_load/on_load_a.erl
@@ -13,7 +13,7 @@ on_load() ->
LibDir = code:lib_dir(kernel),
?MASTER ! {?MODULE,LibDir},
- true.
+ ok.
data() ->
[a|on_load_b:data()].
diff --git a/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl b/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl
index 5c4d676e2d..947cbd5bcd 100644
--- a/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl
+++ b/lib/kernel/test/code_SUITE_data/on_load/on_load_b.erl
@@ -6,7 +6,7 @@ on_load() ->
?MASTER ! {?MODULE,start},
on_load_c:data(),
?MASTER ! {?MODULE,done},
- true.
+ ok.
data() ->
[b|on_load_c:data()].
diff --git a/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl b/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl
index 4b2edbfb5a..6ab7f6402f 100644
--- a/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl
+++ b/lib/kernel/test/code_SUITE_data/on_load/on_load_c.erl
@@ -7,7 +7,7 @@ on_load() ->
receive
go ->
?MASTER ! {?MODULE,done},
- true
+ ok
end.
data() ->
diff --git a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl
index bfc26864d5..a39332f81d 100644
--- a/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl
+++ b/lib/kernel/test/code_SUITE_data/on_load_app-1.0/src/on_load_embedded.erl
@@ -9,7 +9,7 @@ run_me() ->
ok
end
end),
- true.
+ ok.
status() ->
case whereis(everything_is_fine) of
diff --git a/lib/kernel/test/code_SUITE_data/on_load_errors/on_load_error.erl b/lib/kernel/test/code_SUITE_data/on_load_errors/on_load_error.erl
new file mode 100644
index 0000000000..0772050aeb
--- /dev/null
+++ b/lib/kernel/test/code_SUITE_data/on_load_errors/on_load_error.erl
@@ -0,0 +1,13 @@
+-module(on_load_error).
+-on_load(on_load/0).
+-export([main/0]).
+
+on_load() ->
+ ?MASTER ! {?MODULE,self()},
+ receive
+ fail -> erlang:error(failed);
+ Ret -> Ret
+ end.
+
+main() ->
+ ok.
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index b323d86ea4..978541e470 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -1272,6 +1272,9 @@ get_general_info(Fd,GenInfo) ->
get_general_info(Fd,GenInfo#general_info{system_vsn=val(Fd)});
"Compiled" ->
get_general_info(Fd,GenInfo#general_info{compile_time=val(Fd)});
+ "Taints" ->
+ Val = case val(Fd) of "-1" -> "(none)"; Line -> Line end,
+ get_general_info(Fd,GenInfo#general_info{taints=Val});
"Atoms" ->
get_general_info(Fd,GenInfo#general_info{num_atoms=val(Fd)});
"=" ++ _next_tag ->
diff --git a/lib/observer/src/crashdump_viewer.hrl b/lib/observer/src/crashdump_viewer.hrl
index 386d3bb423..6ce727cd3e 100644
--- a/lib/observer/src/crashdump_viewer.hrl
+++ b/lib/observer/src/crashdump_viewer.hrl
@@ -26,6 +26,7 @@
slogan,
system_vsn,
compile_time,
+ taints,
node_name,
num_atoms,
num_procs,
diff --git a/lib/observer/src/crashdump_viewer_html.erl b/lib/observer/src/crashdump_viewer_html.erl
index 5fa829ed37..5e7bbf62a0 100644
--- a/lib/observer/src/crashdump_viewer_html.erl
+++ b/lib/observer/src/crashdump_viewer_html.erl
@@ -215,6 +215,8 @@ general_info_body(Heading,GenInfo) ->
td(GenInfo#general_info.system_vsn)]),
tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Compiled"),
td(GenInfo#general_info.compile_time)]),
+ tr([th("ALIGN=left BGCOLOR=\"#8899AA\"","Taints"),
+ td(GenInfo#general_info.taints)]),
case GenInfo#general_info.mem_tot of
"" -> "";
MemTot ->
diff --git a/lib/orber/doc/src/Makefile b/lib/orber/doc/src/Makefile
index 40f5ef8708..c82db49c9b 100644
--- a/lib/orber/doc/src/Makefile
+++ b/lib/orber/doc/src/Makefile
@@ -64,7 +64,6 @@ XML_REF3_FILES = \
orber_acl.xml
XML_PART_FILES = \
- part_notes_history.xml \
part.xml \
part_notes.xml
@@ -85,10 +84,6 @@ XML_CHAPTER_FILES = \
ch_orberweb.xml \
ch_debugging.xml
-XML_HTML_FILES = \
- notes_history.xml
-
-
BOOK_FILES = book.xml
XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) \
@@ -124,7 +119,6 @@ INTERNAL_HTML_FILES = $(TECHNICAL_DESCR_FILES:%.xml=$(HTMLDIR)/%.html)
HTML_FILES = $(XML_APPLICATION_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html) \
- $(XML_HTML_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_PART_FILES:%.xml=$(HTMLDIR)/%.html)
INFO_FILE = ../../info
diff --git a/lib/orber/doc/src/ch_contents.xml b/lib/orber/doc/src/ch_contents.xml
index 65383805b3..602955764d 100644
--- a/lib/orber/doc/src/ch_contents.xml
+++ b/lib/orber/doc/src/ch_contents.xml
@@ -112,8 +112,8 @@ A concise history of Orber.</p>
<title>IDL to Erlang Mapping</title>
<p>The OMG IDL mapping for Erlang, which is necessary to access the
functionality of Orber, is described, The mapping structure is
- included as the\011basic and the constructed OMG IDL types
- references, invocations\011and Erlang characteristics. An example is
+ included as the basic and the constructed OMG IDL types
+ references, invocations and Erlang characteristics. An example is
also provided.</p>
</section>
diff --git a/lib/orber/doc/src/ch_example.xml b/lib/orber/doc/src/ch_example.xml
index d4cc5ceddc..f2ccfcc7e1 100644
--- a/lib/orber/doc/src/ch_example.xml
+++ b/lib/orber/doc/src/ch_example.xml
@@ -45,7 +45,7 @@
<title>Generating Erlang Code</title>
<p>Run the IDL compiler on this file by calling the <c>ic:gen/1</c> function </p>
<code type="erl">
-\0111> ic:gen("stack").
+ 1> ic:gen("stack").
</code>
<p>This will produce the client stub and server skeleton. Among other files a stack API module named <c>StackModule_Stack.erl</c>
will be produced.
diff --git a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
index 0e2b049ab9..a97ad65f0e 100644
--- a/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
+++ b/lib/orber/doc/src/ch_idl_to_erlang_mapping.xml
@@ -286,15 +286,15 @@ typedef string<10> myString10;
typedef wstring<10> myWString10;
]]></code>
<p>If we want to define a char/string or wchar/wstring constant, we can
- use octal (\\OOO - one, two or three octal digits),
- hexadecimal (\\xHH - one or two hexadecimal digits) and unicode (\\uHHHH -
+ use octal (\OOO - one, two or three octal digits),
+ hexadecimal (\xHH - one or two hexadecimal digits) and unicode (\uHHHH -
one, two, three or four hexadecimal digits.) representation as well.
For example:</p>
<code type="none">
-const string SwedensBestSoccerTeam = "\\101" "\\x49" "\\u004B";
-const wstring SwedensBestHockeyTeam = L"\\101\\x49\\u004B";
-const char aChar = '\\u004B';
-const wchar aWchar = L'\\u004C';
+const string SwedensBestSoccerTeam = "\101" "\x49" "\u004B";
+const wstring SwedensBestHockeyTeam = L"\101\x49\u004B";
+const char aChar = '\u004B';
+const wchar aWchar = L'\u004C';
</code>
<p>Naturally, we can use <c>"Erlang"</c>, <c>L"Rocks"</c>, <c>'A'</c>
and <c>L'A'</c> as well.</p>
@@ -697,14 +697,14 @@ module DB {
module x {
struct y_z {
-\011...
+ ...
};
interface y {
-\011struct z {
-\011 ...
-\011};
+ struct z {
+ ...
+ };
};
};
</code>
@@ -815,7 +815,7 @@ module m {
const float pi = 3.14;
interface i {
-\011const float pi = 3.1415;
+ const float pi = 3.1415;
};
};
</code>
@@ -1036,19 +1036,19 @@ $> erlc +"{be,erl_template}" DB.idl
%% Description:
%%----------------------------------------------------------------------
logon(State, ID, PW) ->
-\011%% Check if the ID/PW is valid and what
-\011%% type of user it is (Common or Administrator).
-\011OE_Reply
+ %% Check if the ID/PW is valid and what
+ %% type of user it is (Common or Administrator).
+ OE_Reply
= case check_user(ID, PW) of
-\011 {ok, administrator} ->
-\011 'DB_Administrator':oe_create();
-\011 {ok, common} ->
-\011 'DB_CommonUser':oe_create();
-\011 error ->
-\011 %% Here we should throw an exception
- \011 corba:raise(....)
+ {ok, administrator} ->
+ 'DB_Administrator':oe_create();
+ {ok, common} ->
+ 'DB_CommonUser':oe_create();
+ error ->
+ %% Here we should throw an exception
+ corba:raise(....)
end,
-\011{reply, OE_Reply, State}.
+ {reply, OE_Reply, State}.
%%======================================================================
%% Internal Functions
@@ -1064,7 +1064,7 @@ logon(State, ID, PW) ->
%% Description: Initiates the server
%%----------------------------------------------------------------------
init(_Env) ->
-\011{ok, #state{}}.
+ {ok, #state{}}.
%%----------------------------------------------------------------------
@@ -1076,7 +1076,7 @@ init(_Env) ->
%% Description: Invoked when the object is terminating.
%%----------------------------------------------------------------------
terminate(_Reason, _State) ->
-\011ok.
+ ok.
%%----------------------------------------------------------------------
@@ -1090,7 +1090,7 @@ terminate(_Reason, _State) ->
%% due to code replacement.
%%----------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
-\011{ok, State}.
+ {ok, State}.
%%----------------------------------------------------------------------
@@ -1104,7 +1104,7 @@ code_change(_OldVsn, State, _Extra) ->
%% Description: Invoked when, for example, the server traps exits.
%%----------------------------------------------------------------------
handle_info(_Info, State) ->
-\011{noreply, State}.
+ {noreply, State}.
]]></code>
<p>Since <c>DB_Administrator</c> inherits from <c>DB_CommonUser</c>,
we must implement <c>delete</c> in the <c>DB_Administrator_impl.erl</c>
@@ -1421,11 +1421,11 @@ interface i {
</row>
<row>
<cell align="left" valign="middle">{tk_objref, IFRId, Name}</cell>
- <cell align="left" valign="middle">{tk_objref, "IDL:M1\\I1:1.0", "I1"}</cell>
+ <cell align="left" valign="middle">{tk_objref, "IDL:M1\I1:1.0", "I1"}</cell>
</row>
<row>
<cell align="left" valign="middle">{tk_struct, IFRId, Name, [{ElemName, ElemTC}]}</cell>
- <cell align="left" valign="middle">{tk_struct, "IDL:M1\\S1:1.0", "S1", [{"a", tk_long}, {"b", tk_char}]}</cell>
+ <cell align="left" valign="middle">{tk_struct, "IDL:M1\S1:1.0", "S1", [{"a", tk_long}, {"b", tk_char}]}</cell>
</row>
<row>
<cell align="left" valign="middle">{tk_union, IFRId, Name, DiscrTC, DefaultNr, [{Label, ElemName, ElemTC}]} <br></br>
diff --git a/lib/orber/doc/src/ch_install.xml b/lib/orber/doc/src/ch_install.xml
index eee2b99c92..ab5885954b 100644
--- a/lib/orber/doc/src/ch_install.xml
+++ b/lib/orber/doc/src/ch_install.xml
@@ -483,7 +483,7 @@ nodeB@hostB> orber:start().
<item>Since Orber domains, they are supposed to communicate via IIOP,
<em>MUST</em> have unique names, communication will
fail if two domains have the same name. The domain name <em>MAY NOT</em>
- contain <c>^G</c> (i.e. <c>\\007</c>).</item>
+ contain <c>^G</c> (i.e. <c>\007</c>).</item>
<tag><em>iiop_port</em></tag>
<item>If set to 0 the OS will pick any vacant port.
<br></br>
@@ -595,7 +595,7 @@ nodeB@hostB> orber:start().
the <c>interceptors</c> parameter.</item>
<tag><em>orbInitRef</em></tag>
<item>Setting this option, e.g.,
- <c>erl -orber orbInitRef [\\"NameService=corbaloc::host.com/NameService\\"]</c>,
+ <c>erl -orber orbInitRef [\"NameService=corbaloc::host.com/NameService\"]</c>,
will alter the location from where <c>corba:resolve_initial_references(Key)</c>
tries to find an object matching the given Key. The keys will also appear when
invoking <c>corba:list_initial_services()</c>. This variable overrides
@@ -605,7 +605,7 @@ nodeB@hostB> orber:start().
found, and this variable is set, it determines the location from where
<c>orber:resolve_initial_references(Key)</c> tries to find an object
matching the given Key. Usage:
- <c>erl -orber orbDefaultInitRef \\"corbaloc::host.com\\"</c>.</item>
+ <c>erl -orber orbDefaultInitRef \"corbaloc::host.com\"</c>.</item>
<tag><em>orber_debug_level</em></tag>
<item>The range is 0 to 10.
Using level 10 is the most verbose configuration.
diff --git a/lib/orber/doc/src/ch_interceptors.xml b/lib/orber/doc/src/ch_interceptors.xml
index 27b254c4bf..af8c5a45f1 100644
--- a/lib/orber/doc/src/ch_interceptors.xml
+++ b/lib/orber/doc/src/ch_interceptors.xml
@@ -188,17 +188,17 @@ out_reply_encoded({ObjTable, ChecksumModule}, ObjKey, Ctx, Op, Bin, Extra) ->
%% Interceptor functions.
-export([new_out_connection/3,
-\011 new_in_connection/3,
-\011 closed_in_connection/1,
-\011 closed_out_connection/1,
-\011 in_request_encoded/6,
-\011 in_reply_encoded/6,
-\011 out_reply_encoded/6,
-\011 out_request_encoded/6,
-\011 in_request/6,
-\011 in_reply/6,
-\011 out_reply/6,
-\011 out_request/6]).
+ new_in_connection/3,
+ closed_in_connection/1,
+ closed_out_connection/1,
+ in_request_encoded/6,
+ in_reply_encoded/6,
+ out_reply_encoded/6,
+ out_request_encoded/6,
+ in_request/6,
+ in_reply/6,
+ out_reply/6,
+ out_request/6]).
new_in_connection(Arg, Host, Port) ->
%% Since we only use one interceptor we do not care about the
diff --git a/lib/orber/doc/src/ch_naming_service.xml b/lib/orber/doc/src/ch_naming_service.xml
index 510ccf2543..5cc50d95ec 100644
--- a/lib/orber/doc/src/ch_naming_service.xml
+++ b/lib/orber/doc/src/ch_naming_service.xml
@@ -116,7 +116,7 @@ Figure 1: Contextual object relationships using the Naming Service.</icaption>
<p>In order to use the naming service you have to fetch an
initial reference to it. This is done with:</p>
<code type="none">
-\011NS = corba:resolve_initial_references("NameService").
+NS = corba:resolve_initial_references("NameService").
</code>
<note>
<p>NS in the other use-cases refers to this initial reference.</p>
@@ -208,17 +208,17 @@ Sc = corba:string_to_object("corbaname:rir:/NameService#workgroup/services/").
{BList, BIterator} = 'CosNaming_NamingContext':list(Sc, 10).
lists:foreach(fun({{Id, Kind},BindingType}) -> case BindingType of
-\011nobject ->
-\011\011io:format("id: %s, kind: %s, type: object~n", [Id, Kind]);
-\011 _ ->
-\011\011io:format("id: %s, kind: %s, type: ncontext~n", [Id, Kind])
-\011end end,
-\011Blist).
+ nobject ->
+ io:format("id: %s, kind: %s, type: object~n", [Id, Kind]);
+ _ ->
+ io:format("id: %s, kind: %s, type: ncontext~n", [Id, Kind])
+ end end,
+ Blist).
</code>
</item>
</list>
<note>
- <p>Normally a <term id="BindingIterator"><termdef>The binding iterator (Like a book mark) indicates which objects have been read from the list.</termdef></term>is helpful in situations where you have a large\011number of objects
+ <p>Normally a <term id="BindingIterator"><termdef>The binding iterator (Like a book mark) indicates which objects have been read from the list.</termdef></term>is helpful in situations where you have a large number of objects
in a list, as the programmer then can traverse it more easily.
In Erlang it is not needed, because lists are easily handled in the
language itself.</p>
@@ -427,7 +427,7 @@ lists:foreach(fun({{Id, Kind},BindingType}) -> case BindingType of
<cell align="left" valign="middle">An Id with a trailing '.' is not allowed.</cell>
</row>
<row>
- <cell align="left" valign="middle">"i\\\\/d1/i\\\\.d2"</cell>
+ <cell align="left" valign="middle">"i\\/d1/i\\.d2"</cell>
<cell align="left" valign="middle">[{"i/d1",""},{"i.d2",""}]</cell>
<cell align="left" valign="middle">Since '.' and '/' are used to separate the components, these tokens must be escaped to be correctly converted.</cell>
</row>
diff --git a/lib/orber/doc/src/corba.xml b/lib/orber/doc/src/corba.xml
index 6c89279733..cae0e09b0b 100644
--- a/lib/orber/doc/src/corba.xml
+++ b/lib/orber/doc/src/corba.xml
@@ -99,9 +99,8 @@
<em>MAY ONLY</em> be used during testing and development.</p>
<code type="none">
Example:
-\011
- corba:create('StackModule_Stack', "IDL:StackModule/Stack:1.0",
-\011 {10, test})
+
+ corba:create('StackModule_Stack', "IDL:StackModule/Stack:1.0", {10, test})
</code>
</desc>
</func>
diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml
index 08bbf4b29c..1185b7658f 100644
--- a/lib/orber/doc/src/notes.xml
+++ b/lib/orber/doc/src/notes.xml
@@ -33,6 +33,24 @@
</header>
<section>
+ <title>Orber 3.6.15</title>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <list type="bulleted">
+ <item>
+ <p>Removed superfluous VT in the documentation.</p>
+ <p>Own id: OTP-8353 Aux Id:</p>
+ </item>
+ <item>
+ <p>Removed superfluous backslash in the documentation.</p>
+ <p>Own id: OTP-8354 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+ </section>
+
+ <section>
<title>Orber 3.6.14</title>
<section>
@@ -403,8 +421,6 @@
</item>
</list>
</section>
- <!-- p>For information about older versions see
- <url href="part_notes_history_frame.html">release notes history</url>.</p -->
</section>
</chapter>
diff --git a/lib/orber/doc/src/notes_history.xml b/lib/orber/doc/src/notes_history.xml
deleted file mode 100644
index b493f0e379..0000000000
--- a/lib/orber/doc/src/notes_history.xml
+++ /dev/null
@@ -1,1523 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2004</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>Orber Release Notes History</title>
- <prepared></prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date>99-02-12</date>
- <rev>A</rev>
- </header>
-
- <section>
- <title>Orber 3.5.4</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>In some cases, it was possible for a user to delete the
- NameService root context.</p>
- <p>Own Id: OTP-5202</p>
- </item>
- <item>
- <p>Invoking two, or more, concurrent oe_register operations
- it could corrupt the IFR. If this is the case, the
- INTF_REPOS system exception is raised. The risk for this
- to occur is rather slim.</p>
- <p>Own Id: OTP-5526</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.5.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>To avoid malicious attacks, it is now possible to configure
- Orber to only accept incoming requests up to a certain size.
- To be able to use this option, it must be supported by inet
- and SSL.</p>
- <p>Own id: OTP-5129</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.5.2</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>If a client tried to connect to Orber and immediately
- closed the connection, then the process accepting new
- connections could end up with a message in the queue
- that would never be removed.</p>
- <p>Own id: OTP-5105</p>
- </item>
- <item>
- <p>The INS corbaloc/corbaname URL:s did only accept DNS style host
- names. Now it is also possible to use, none compressed, IPv6
- addresses.</p>
- <p>Own id: OTP-5108</p>
- </item>
- <item>
- <p>When Orber was configured to use IPv6 for inter-ORB communication,
- exported IOR:s did not contain a correct IPv6 address. This did not
- cause any problems if Orber was configured to use DNS style hostname
- instead.</p>
- <p>Own id: OTP-5109</p>
- </item>
- <item>
- <p>Orber used external operations not exported in R9B.</p>
- <p>Own id: OTP-5111</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.5.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When using Light IFR it was not possible unregister data
- (i.e., invoking 'MyModule':oe_unregister()).
- Introduced in Orber-3.5.0.1.</p>
- <p>Own id: OTP-5034</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.5.0.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>orber_ifr:contents/3 always returned an empty list when using
- Light IFR. Little or no effect.</p>
- <p>Own id: OTP-5018</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.5</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>It is now possible to configure Orber to use NAT (Network Address
- Translation) friendly parameters. A new section in the User's Guide
- describes how to handle communication via firewalls.</p>
- <p>Own id: OTP-4698</p>
- </item>
- <item>
- <p>A new module called <c>orber_diagnostics</c> have been added, which
- is intended to aid a user during the test and development phase.
- For more information, see the reference manual.</p>
- <p>Own id: OTP-4699</p>
- </item>
- <item>
- <p><c>IPv6</c> supported.</p>
- <p>Own id: OTP-4937</p>
- </item>
- <item>
- <p>Possible to configure Orber so that exported IOR:s contain
- multiple IIOP components for different interfaces.</p>
- <p>Own id: OTP-4938</p>
- </item>
- <item>
- <p>Improved typechecking of typecode supplied to the operations
- <c>orber_tc:check_tc/1</c>, <c>any:create/2</c> and
- <c>any:set_typecode/2</c>.</p>
- <p>Own id: OTP-4939</p>
- </item>
- <item>
- <p>Server objects can now be started as EXIT tolerant.</p>
- <p>Own id: OTP-4940</p>
- </item>
- <item>
- <p>Possible to use interceptors for local invocations as well.</p>
- <p>Own id: OTP-4941</p>
- </item>
- <item>
- <p>If the IFR is not explicitly used, Orber can be configured
- to use a minimal IFR to reduce memory usage and installation
- time.</p>
- <p>Own id: OTP-5001</p>
- </item>
- <item>
- <p>To avoid malicious attacks it is now possible to configure
- Orber to limit the number of concurrent connections and
- requests and the amount of IIOP fragments.</p>
- <p>Own id: OTP-5002</p>
- </item>
- <item>
- <p>The operation <c>orber:iiop_connections/0</c> now also include
- incoming connections.</p>
- <p>Own id: OTP-5004</p>
- </item>
- <item>
- <p>The function <c>orber:add_node/2</c> now accepts more options.</p>
- <p>Own id: OTP-5006</p>
- </item>
- <item>
- <p>The module <c>orber_diagnostics</c> now exports a function
- which list missing modules generated by IC and required by
- Orber.</p>
- <p>Own id: OTP-5007</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Orber's NameService did not return a NIL object reference if the total
- number of existing bindings was less than, or equal to,
- the <c>HowMany</c> parameter passed to
- <c>'CosNaming_NamingContext':list/2</c> operation. This have now been
- changed to be compliant with the OMG standard. Furthermore, the operation
- <c>'CosNaming_BindingIterator':next_n/2</c> did not handle the index
- correctly in all situations.</p>
- <p>Own id: OTP-4700</p>
- </item>
- <item>
- <p>If the Orber internal gen_server orber_iiop_pm was stopped
- in such a way that the terminate function was not invoked,
- then ghost processes would appear.</p>
- <p>Own id: OTP-5003</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>The work-around introduced in version 3.4.1 (OTP-4608) has
- now been removed. Make sure you are using IC-4.2 or later.</p>
- </item>
- <item>
- <p>Since the OMG has defined a default port number (2809),
- Orber no longer support the bootstrap port.</p>
- <p>Own id: OTP-5005</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.4.2.2</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Due to IFR DB lock mechanisms, concurrent creation
- of non-anonymous IFR types could still result in duplicated
- entries.</p>
- <p>Own id: OTP-4781</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.4.2.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The operation <c>orber:start()</c> could return before
- all Mnesia tables were accessible.</p>
- <p>Own id: OTP-4780</p>
- </item>
- <item>
- <p>Concurrent creation of non-anonymous IFR types
- could result in duplicates in the DB.</p>
- <p>Own id: OTP-4781</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.4.2</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Improved type tests for string, wide string and sequence when
- passed via IIOP.</p>
- <p>Own id: OTP-4759</p>
- </item>
- <item>
- <p>Less (internal) processes are needed when Orber act as client-side ORB
- and communicate with another ORB. Due to this change, closed connections
- and socket errors are dealt with in a more gentle way. If the latter
- occurs, the error_logger application is used to generate an error
- report containing a description of what went wrong.</p>
- <p>Own id: OTP-4655</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When communicating with another ORB, via SSL, and a socket error occurred,
- Orber did not recognize the error message. This occurred when Orber
- acted as client-side ORB.</p>
- <p>Own id: OTP-4656</p>
- </item>
- <item>
- <p>If an out-going connection was closed and the receiving process had not
- been scheduled yet, the close connection message was delivered before
- the correct message.</p>
- <p>Own id: OTP-4657</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Since strstream is deprecated and not accepted by gcc-3.3,
- Orber no longer includes the InitalReference lib. The source
- code is still included.</p>
- <p>Own id: OTP-4767</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.4.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>It is now possible to use IC-versions older than 4.2. But, this is
- only temporary so it is still necessary upgrade to a correct
- version.</p>
- <p>Own id: OTP-4608</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.4</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>If a call-back module illegally caused an EXIT, clients
- residing on another ORB was not notified (hanged).</p>
- <p>Own id: OTP-4577</p>
- </item>
- <item>
- <p>The stub/skeleton-files generated by IC have been improved,
- i.e., depending on the IDL-files, reduced the size of the
- erl- and beam-files and decreased dependencies off Orber's
- Interface Repository. It is necessary to re-compile all IDL-files
- and use COS-applications, including Orber, compiled with
- IC-4.2.</p>
- <p>Own id: OTP-4576</p>
- </item>
- <item>
- <p>It is now possible to configure Orber to use the host name
- in exported IOR:s instead of the IP-number.</p>
- <p>Own id: OTP-4541</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When Orber acted as server-side ORB and one tried to setup a
- SSL-connection and using native Interceptors at the same time
- it failed.</p>
- <p>Own Id: OTP-4542</p>
- </item>
- <item>
- <p>Oneway operations, using a multi-node Orber, failed for inter-node
- communication.</p>
- <p>Own Id: OTP-4543</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Orber now supports fragmented IIOP messages for 1.2.</p>
- <p>Own Id: OTP-4462</p>
- </item>
- <item>
- <p>Orber now has its own set of unique VMCID:s which
- is used for minor codes in system exceptions. All system exceptions raised
- by Orber now uses this VMCID base or OMG:s VMCID base. See also the function
- <c>orber:exception_info/1</c>.</p>
- <p>Own Id: OTP-4463</p>
- </item>
- <item>
- <p>Since some ORB:s, non-compliant with the OMG specification,
- have problems using IOR:s which embeds a CodeSet component, it is now
- possible to configure Orber to exclude it from exported IOR:s.</p>
- <p>Own Id: OTP-4469</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When combining interceptors and oneway operations, Orber
- incorrectly sent a MessageError over the connection to the
- client ORB.</p>
- <p>Own Id: OTP-4460</p>
- </item>
- <item>
- <p>After (2^32)-1 requests, Orber used the request number 0 twice
- in a row.</p>
- <p>Own Id: OTP-4461</p>
- </item>
- <item>
- <p>The COMM_FAILURE exception should only be raised when connection
- problems occur. Now Orber raises the correct exceptions. Note, when
- Orber act as client side ORB you must be able to handle any of the system
- exceptions defined by the OMG. Some of the COMM_FAILURE exceptions
- have been replaced with the correct TRANSIENT and TIMEOUT exceptions.</p>
- <p>Own Id: OTP-4465</p>
- </item>
- <item>
- <p>The default port used for corbaloc and corbaname was
- incorrect. Now changed to follow the OMG standard (2809).</p>
- <p>Own Id: OTP-4466</p>
- </item>
- <item>
- <p>When Orber acted as a client-side ORB, it failed to encode
- unions with a default case (i.e. defined in the IDL-code and a
- default label used).</p>
- <p>Own Id: OTP-4472</p>
- </item>
- <item>
- <p>The operation corba:print_object/1/2 did not include host/port
- data for IIOP-1.0 IOR:s.</p>
- <p>Own Id: OTP-4483</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Some of the COMM_FAILURE exceptions have been replaced with the correct
- TRANSIENT and TIMEOUT exceptions. All minor codes used by Orber
- is now based on the OMG assigned VMCIDs.</p>
- <p>Own Id: OTP-4465, OTP-4463</p>
- </item>
- <item>
- <p>The default port used for corbaloc and corbaname have been changed
- to 2809.</p>
- <p>Own Id: OTP-4466</p>
- </item>
- <item>
- <p>To reduce extra overhead Orber now uses a flag parameter,
- which makes it possible to configure Orber's behavior in different ways.
- Hence, the global activation of Local Typechecking, introduced in the previous
- version, have now been changed.</p>
- <p>Own Id: OTP-4467</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.13</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>It is now possible to activate automatic typechecking when
- invoking operations on CORBA Objects locally. For more
- information, see the configuration and debugging chapters
- in the User's Guide regarding the <c>local_typecheck</c>
- option.</p>
- <p>Own Id: OTP-4410</p>
- </item>
- <item>
- <p>Due to the success of the pre-compiled IIOP-trace interceptor, a less
- verbose trace interceptor, called <c>orber_iiop_tracer_silent</c>,
- have been added as well.</p>
- <p>Own Id: OTP-4257</p>
- </item>
- <item>
- <p>Orber now support the Fixed datatype defined by the OMG. To be able
- to define Fixed types in an IDL-specification, check that your current
- IC version supports this type as well. If not, the only option is
- to encapsulate it in an <c>any</c> type.</p>
- <p>Own id: OTP-4375</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>It was not possible to use the function <c>corba:print_object/2</c>,
- which was introduced in the previous release, only
- <c>corba:print_object/1</c>. Now it is also possible to use
- the <c>error_logger</c> or receive the data in string form.</p>
- <p>Own Id: OTP-4376</p>
- </item>
- <item>
- <p>The functions <c>orber_tc:principal</c> and <c>orber_tc:exception</c>
- returned incorrect.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>The function <c>orber_ifr:get_primitive</c> tried to access a
- non-existing (primitivdefs) table.</p>
- <p>Own Id: -</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.12</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Orber now check if an external IOR contains any
- TAG_ALTERNATE_IIOP_ADDRESS components when trying to setup
- a connection to another ORB.</p>
- <p>Own id: OTP-4294</p>
- </item>
- <item>
- <p>It is now possible to add TAG_ALTERNATE_IIOP_ADDRESS components
- to a local object reference. See corba:add_alternate_iiop_address/3.</p>
- <p>Own id: OTP-4294</p>
- </item>
- <item>
- <p>Orber now allows unions with no default value defined and a
- discriminator out of range to be sent via IIOP. The value-field
- is set to the atom undefined.</p>
- <p>Own id: OTP-4295</p>
- </item>
- <item>
- <p>The corba module now exports a function, print_object/1/2, which
- prints IOR's in a more readable form.</p>
- <p>Own id: OTP-4296</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Since "all" ORB's accept ISO-8859-1 encoding of chars and strings,
- Orber assumed that it could be used at all time to reduce the overhead.
- The JDK-1.3 only accepts ISO 646:1991 IRV (US-ASCII), even though
- ISO-8859-1 is default, which is why Orber now checks which codeset
- is accepted.</p>
- <p>Own Id: OTP-4298</p>
- </item>
- <item>
- <p>When invoking a Locate Request, Orber in some cases did not reply
- with a Locate Reply header (used a Reply header).</p>
- <p>Own Id: OTP-4293</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.11</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>If the underlying OS was not configured to allow Erlang to use the
- fully qualified host name the result could an incorrect IP-address.
- Hence, if you want to upgrade to Orber-3.2.11 and the fully
- qualified name must be used you must upgrade your kernel version.
- Most likely, this change will NOT cause any problems, but if in doubt
- please contact support or use the mailing-list.
- See also the release notes for Orber-3.2.6.</p>
- <p>Own id: OTP-3966</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When looking up Initial Service (e.g. using <c>corbaloc</c>,
- <c>corbaname</c> or <c>corba:resolve_initial_references_remote/2</c>)
- and communicating via SSL, Orber used the wrong port number.</p>
- <p>Own Id: OTP-4264</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.10</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>It is now possible to add new initial references, which can,
- for example, be accessed via <c>corba:resolve_initial_references/1</c>
- or the <c>corbaloc</c> schema.</p>
- <p>Own Id: OTP-4258</p>
- </item>
- <item>
- <p>The orber module now exports functions, <c>iiop_connections</c>
- and <c>iiop_connections_pending</c>, which, respectively, list
- all currently open connections to other ORB's and connections
- which are in process of being set up to another ORB.</p>
- <p>Own Id: OTP-4262</p>
- </item>
- <item>
- <p>Orber now allows the user to define an interval of ports
- which Orber is may use (i.e. ports on the local machine)
- when trying to connect to another ORB. This behavior is useful
- if Orber resides behind a firewall which only allow applications
- to use certain ports when communicating with the outside world.
- If this option is set, it is absolutely necessary to
- set <c>iiop_connection_timeout</c>. If not, there is risk that
- Orber run out of ports, which will result in communication failure.
- This option cannot be used when using SSL since it does not support
- this feature. The default behavior is that any available port
- will be used (as before).</p>
- <p>Own Id: OTP-4260</p>
- </item>
- <item>
- <p>One can now install Orber's NameService as disc_copies, but
- the default behavior is that Orber uses ram_copies.</p>
- <p>Own Id: OTP-4259</p>
- </item>
- <item>
- <p>A pre-compiled IIOP-trace interceptor is now
- included in the Orber release. For more information,
- see the <c>Debugging</c> chapter in the User's Guide.</p>
- <p>Own Id: OTP-4257</p>
- </item>
- <item>
- <p>It is now possible to set Orber's configuration parameters
- in, for example, an Erlang shell. Consult <c>corba:orb_init/1</c> and
- <c>orber:configure/2</c>.</p>
- <p>Own Id: OTP-4261</p>
- </item>
- <item>
- <p>The Orber release now include <c>OrberWeb</c>, which is an extension of
- the <c>WebTool</c> application (first released in R8B). Hence,
- <c>WebTool</c> must be installed to enable this feature. For more
- information, see the chapter <c>OrberWeb</c> in the User's Guide.
- <c>OrberWeb</c> is intended to be used during test and development.</p>
- <p>Own Id: OTP-4257</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When setting up two Orber ORB's, where one of the ORB's domain
- name was a prefix of the other ORB's, communication via IIOP would fail.
- To eliminate any further configuration problems, one may not
- use <c>^G</c> (i.e. <c>"\\007"</c>) in the domain name. Due to this
- change it is not possible to upgrade during run-time.</p>
- <p>Own Id: OTP-4229</p>
- </item>
- <item>
- <p>When using a mix of IIOP-versions (1.0 vs 1.1/1.2) and
- sending/receiving IOR's to/from Orber could result in a
- MARSHAL exception.</p>
- <p>Own Id: OTP-4230</p>
- </item>
- <item>
- <p>Encoding/decoding of wchar/wstring when using IIOP-1.2 do now
- follow the OMG standard. If your ORB do not follow the
- standard, contact support for information how to make a work-around
- to solve this problem. In most cases it is sufficient to
- configure the ORB's to communicate via IIOP-1.1.</p>
- <p>Own Id: OTP-4263</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>The encoding/decoding of wchar/wstring when using IIOP-1.2
- have been updated. See above.</p>
- <p>Own Id: OTP-4263</p>
- </item>
- <item>
- <p>Orber no longer returns a 'EXIT' message when trying
- to install Orber, i.e., invoking orber:install/1/2,
- on a disc-less node. But if if the installation fails due
- to any other reason, Orber still return a 'EXIT' message.</p>
- <p>Own Id: OTP-4256</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Known bugs and problems</title>
- <list type="bulleted">
- <item>
- <p><c>OrberWeb</c> only tested with <c>Netscape-4.75</c>. Furthermore,
- until <c>WebTool</c> reaches version 1.0 OrberWeb should also
- be considered to be a beta version.</p>
- <p>Own Id: OTP-4257</p>
- </item>
- <item>
- <p><c>OrberWeb</c> do not escape arguments passed when, for example,
- creating a new context. Hence, for now you are recommended to
- only use letters.</p>
- <p>Own Id: OTP-4257</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.9</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>External IOR:s containing unsupported or incorrectly placed
- TaggedComponents was corrupted when Orber forwarded the
- IOR via IIOP. This bug was introduced in 3.2.6.</p>
- <p>Own Id: OTP-4170</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.8</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Orber now support interceptors.</p>
- <p>Own Id: -</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.7</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>When Orber acted as server-side and communicating via IIOP the overhead
- was unreasonably large and memory consuming (depended on the
- IDL-specification). This have now been fixed and will, especially,
- improve the performance when invoking operations with no, or simple,
- arguments on a complex interface. This change will have little effect
- on objects started as pseudo since this problem did not affect them.</p>
- <p>Own Id: OTP-4063</p>
- </item>
- <item>
- <p>When Orber tried to set up a connection to another ORB which did not
- respond all IIOP access where blocked until the TCP protocol
- generated a timeout. Now only requests to that particular ORB are
- queued.</p>
- <p>Own Id: OTP-4060</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>It was not possible to invoke the operation
- CosNaming_BindingIterator:next_one via IIOP if no more bindings
- existed.</p>
- <p>Own id: OTP-4004</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.6</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Registering data in the IFR overhead reduced.</p>
- <p>Own id: OTP-3904</p>
- </item>
- <item>
- <p>The overhead for the function <c>is_a/1</c> have been reduced, which also
- affects remote <c>narrow</c> operations for inherited interfaces
- (e.g. using Java or C++ ORBs).</p>
- <p>Own id: OTP-3904</p>
- </item>
- <item>
- <p>If the underlying OS was not configured to allow Erlang to
- lookup the host-name by using the short-name the result was
- always the IP-address 127.0.0.1 (loop-back). Now Orber uses
- the full name. Hence, make sure the <c>net_adm:localhost/0</c> and
- <c>inet:getaddr/2</c> return proper values.</p>
- <p>Own id: OTP-3966</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The CONV_FRAME_CodeSetComponentInfo struct was not placed
- correctly in IOR:s. Each profile must be self-sustained
- which is why this information must be duplicated in each
- profile. Currently this only applies for the IIOP-profile
- but will also concern future protocols.</p>
- <p>Own id: OTP-3992</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.5</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Orber now defines the configuration variable,
- <c>iiop_setup_connection_timeout</c>, which makes it possible to
- timeout connection attempts to another ORB before the OS TCP timeout
- is activated.</p>
- <p>Own id: OTP-3961</p>
- </item>
- <item>
- <p>It is now possible to configure Orber to generate reports when abnormal
- situations occurs. For more information consult the User's Guide
- regarding the configuration parameter <c>orber_debug_level</c>.
- Note, it is not recommended to use this option for delivered systems
- since some of the reports is not to be considered as errors.</p>
- <p>Own id: OTP-3962</p>
- </item>
- <item>
- <p>Orber now accepts a list of addresses as value for the configuration
- parameter <c>orbInitRef</c>.</p>
- <p>Own id: OTP-3945</p>
- </item>
- <item>
- <p>Orber now includes services defined by the configuration parameter
- <c>orbInitRef</c> when invoking <c>corba:list_initial_services/0</c>.</p>
- <p>Own id: OTP-3946</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When using the configuration variable 'orbDefaultInitRef' with
- a value pointing to another Orber-ORB it was not possible to
- install Orber since Orber used to create default <c>NamingContexts</c>.
- Orber no longer add these contexts.</p>
- <p>Own id: OTP-3943</p>
- </item>
- <item>
- <p>Orber accessed <c>corbaloc</c> addresses in reverse order. Now fixed.</p>
- <p>Own id: OTP-3944</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>When installing Orber no default <c>NamingContext's</c>, i.e.,
- <c>host</c>, <c>hosts</c>, <c>resources</c>, <c>development</c>,
- <c>factories</c> and <c>workgroup</c>, will be added. These contexts
- was defined in a cancelled specification.</p>
- <p>Own id: OTP-3942</p>
- </item>
- <item>
- <p><c>corbaloc</c> addresses are now accessed in FIFO order (instead of
- LIFO).</p>
- <p>Own id: OTP-3944</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.4</title>
-
- <section>
- <title>Improvements and New Features</title>
- <p>-</p>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When communicating via IIOP using version 1.2 Orber used incorrect
- offset for reply bodies containing system exceptions, exceptions and
- location forward.</p>
- <p>Own id: OTP-3912</p>
- </item>
- <item>
- <p>Orber did not return correct IFR Id:s when raising system exceptions
- via IIOP.</p>
- <p>Own id: OTP-3911</p>
- </item>
- <item>
- <p>If two different processes concurrently manipulated a
- <c>CosNaming::NamingContext</c> the data could become corrupted.
- For single-node Orber this error occurred in version 3.2.1, 3.2.2 and
- 3.2.3. For multi-node Orber this behavior have been present at all time.</p>
- <p>Own id: OTP-3910</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>Since Orber now returns a different, and correct, IFR-id for
- systems exceptions other ORB:s and older versions of Orber
- might raise a different exception, probably MARSHAL or UNKNOWN.
- This only occurs when communicating via IIOP. It is not possible to
- upgrade during runtime. Use <c>orber:stop()</c>, load new version and
- restart Orber by invoking <c>orber:start()</c>.</p>
- <p>Own id: OTP-3911</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Improved performance for all types, simple and complex, when
- communicating via IIOP. It is not possible to upgrade during
- runtime. Use <c>orber:stop()</c>, load new version and restart
- Orber by invoking <c>orber:start()</c>.</p>
- <p>Own id: OTP-3905</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>If a pseudo object raises an exception or exits the exception
- was only returned, not thrown.</p>
- <p>Own id: OTP-3907</p>
- </item>
- <item>
- <p>Orber defined an incorrect ID for CodeSets. This may cause
- INV_OBJREF or DATA_CONVERSION exceptions to be thrown, it
- depends on the other ORB.</p>
- <p>Own id: OTP-3899</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.2</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The behavior of Orber when receiving unsupported or incorrect
- messages have now been improved.</p>
- <p>Own id: OTP-3903</p>
- </item>
- <item>
- <p>Time consumed by <c>oe_MyModule:oe_register()</c> decreased.</p>
- <p>Own id: OTP-3904</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When Orber received a 'location_forward' reply, the result
- from the second invocation was never delivered to the
- client. Now fixed.</p>
- <p>Own id: OTP-3814</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>It is now possible to use external <c>NamingContexts</c>
- when, for example, using
- <c>'CosNaming_NamingContextExt':bind_context/3</c>.</p>
- <p>Own id: OTP-3902</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.2</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Orber now supports IIOP-version 1.2.</p>
- <p>Own id: OTP-3901</p>
- </item>
- <item>
- <p>Improved encoding and decoding performance for IIOP requests containing
- <c>struct</c>, <c>union</c> or user defined <c>exceptions</c>.</p>
- <p>Own id: OTP-3900</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Setting the <c>bootstrap_port</c> configuration parameter to a value
- less than 1024 made it impossible to start Orber properly.
- Now fixed.</p>
- <p>Own id: OTP-3898</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.8</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Orber now accepts <c>Indirection/Repeated</c><c>CORBA::TypeCode</c> as input and/or
- return value when communicating via IIOP.</p>
- <p>Own id: -</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When another ORB replied with <c>location forward</c> Orber
- failed to decode this. Now fixed.</p>
- <p>Own id: OTP-3709</p>
- </item>
- <item>
- <p>Orber failed to encode <c>CORBA::TypeCode</c> containing <c>tk_alias</c>, e.g.,
- sending an <c>#any{}</c> which encapsulates data defined by <c>typedef</c>.</p>
- <p>Own id: OTP-3689</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.7</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Earlier, Orber did not use the IIOP/GIOP version specified
- in an external object key when invoking an intra-ORB request.</p>
- <p>Own id: OTP-3663</p>
- </item>
- <item>
- <p>The OMG standard now support an Interoperable Naming Service.
- Initially there where two proposals of which Orber earlier
- supported one of them. Now both standards are supported.</p>
- <p>Own id: OTP-3664</p>
- </item>
- <item>
- <p>The OMG have redefined the operator, used when encoding requests via IIOP,
- for the function <c>corba_object:non_existent/1</c>. CORBA version 2.0 and
- 2.2 compliant ORB:s is supposed to support the old definition, while
- later versions, i.e., 2.3, is supposed to use the new operator
- (<c>_non_existent</c> instead of <c>_not_existent</c>). Orber accepts
- both versions.</p>
- <p>Own id: OTP-3679</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>If an Orber node crashed and was restarted the object keys could
- point to other processes than it should, which may cause problems if,
- for example, the other process terminates due to it does not handle
- unknown messages. Now Orber GC object keys for objects residing on the
- crashed node. If Orber is started as a multi-node ORB of which one or
- more nodes runs an older Orber version they can still communicate but
- with an increased overhead. Hence, all nodes should be upgraded during
- a relatively short time. If Orber is stopped, i.e., orber:stop() or
- a shutdown is generated, objects residing on that node will be terminated.</p>
- <p>Own id: OTP-3678</p>
- </item>
- <item>
- <p>If an IDL-file contains two interfaces of which the first one
- contains an exception and the second interface, which inherits the first
- one, contain an operation which raises this exception the IFR
- failed since multiple references where found when invoking
- orber_ifr:lookup_id/2. Now fixed.</p>
- <p>Own id: OTP-3665</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>To be able to start Orber as lightweight the mnesia application
- cannot be listed in the "orber.app" file. You might find it
- necessary to add 'mnesia' to the applications-list.
- For example, you cannot upgrade an older version
- of Orber (not started as lightweight) to this version without
- adding mnesia to the application dependencies list.</p>
- <p>Own id: OTP-3666</p>
- </item>
- <item>
- <p>The function <c>corba_object:non_existent/1</c> have been updated
- to follow the CORBA 2.3 standard. Hence, Intra-ORB communication
- with ORB:s not supporting this standard will fail. The operation
- <c>corba_object:not_existent/1</c> allow users to use the old standard.
- Consult the ORB vendor's documentation to decide which function to use.</p>
- <p>Own id: OTP-3679</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.6</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Cosmetic update of internal functions.</p>
- <p>Own id: -</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When decoding TypeCode for an object reference, e.g., as a part of
- an #any{}, Orber failed. This is no longer the case. </p>
- <p>Own id: OTP-3631</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.4</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The function <c>start_lightweight/1</c> have been added to the
- <c>orber</c> module. This function allow us to start orber as
- lightweight without, or override, the configuration parameter
- <c>-orber lightweight</c>.</p>
- <p>Own id: -</p>
- </item>
- <item>
- <p>A new configuration parameter, 'iiop_connection_timeout Secs', is now
- available. This parameter's purpose, is to terminate the socket
- connection on the client side if a time span of Secs seconds have passed.
- The connection will, however, NOT be terminated if a client still waits
- for a reply. For the last scenario to happen, the client have been
- configured to use a larger timeout value than the configuration
- parameter 'iiop_connection_timeout' have been set to.</p>
- <p>Own id: -</p>
- </item>
- <item>
- <p>Up until now, invoking an an operation with an extra Timeout parameter
- (using the IC option: ic:gen(IdlFile, [{timeout,"module::interface"}])),
- only applied to local Objects. Now, using the IC option above, when
- compiling the stubs, and adding the extra Timeout parameter, a timeout
- will also be triggered when calling Objects residing on other ORB:s.
- The return value, after a timeout has been triggered, have changed from
- an EXIT message to raising the system exception COMM_FAILURE. For more
- information, about how this feature interacts with the configuration
- parameter 'iiop_timeout', consult the documentation.</p>
- <p>Own id: -</p>
- </item>
- <item>
- <p>When using invalid intra-ORB configuration, i.e., incorrect
- Port/IP-address, when trying to connect to another ORB,
- a CRASH REPORT was generated if the configuration
- parameter '-boot start_sasl' was used. This behavior has now changed.</p>
- <p>Own id: -</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>If a client-side ORB terminated the IIOP connection immediately there
- was a possibility that the server responsible detecting this did not.</p>
- <p>Own id: OTP-3593</p>
- </item>
- <item>
- <p>Setting the configuration parameter 'iiop_timeout' did not result in a
- correct behavior, i.e., no timeout triggered.</p>
- <p>Own id: OTP-3555</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>When using the IC option, ic:gen(IdlFile, [{timeout,"module::interface"}]),
- an EXIT was the timeout result. Now, the system exception COMM_FAILURE is
- raised.</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.3</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Orber did not ignore unrecognized TaggedProfiles. Other vendors may have
- registered own TAG's with the OMG. These TAG's are valid but not
- necessarily handled by other vendors.</p>
- <p>Own id: OTP-3514</p>
- </item>
- <item>
- <p>When passing Object references over IIOP, decoding local references could
- fail. Now fixed.</p>
- <p>Own id: OTP-3515</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.2</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Previously the OMG have published two suggestions for <c>Interoperable Name Service</c>,
- of which, the <c>CORBA 3</c> specify <c>orbos/98-10-11</c> to be implemented.
- Unfortunately, the Interoperable Name Service Orber supports, is the one not chosen.
- Hence, the <c>InitialReferences.idl</c> will not be according to the future standard.
- The modules name is now changed from <c>CORBA</c> to <c>Orber</c>. This will affect
- code which are using this interface. The idl specification must be recompiled and
- then <c>CORBA</c> must be changed to <c>Orber</c> in the client.</p>
- <p>Own id: OTP-3468, OTP-3155</p>
- </item>
- <item>
- <p>Now possible to run oe_unregister when the IDL-specification contains
- exceptions correctly.</p>
- <p>Own Id: OTP-3447</p>
- </item>
- <item>
- <p>Now possible to run oe_unregister when the IDL-specification contains
- attributes.</p>
- <p>Own Id: OTP-3439</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <p>The change in <c>InitialReferences.idl</c> to clash with the Corba standard implies changes
- in code that use this interface. See the OTP-3468 and OTP-3155 in the <c>Fixed Bugs and Malfunctions</c>
- chapter above.</p>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1.1</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>When introducing the configuration parameter <c>ip_address</c>
- it was no longer possible to have the same default behavior
- as before. Now fixed.</p>
- <p>Own Id: OTP-3431</p>
- </item>
- <item>
- <p>The internal request number handling never checked if maximum reached.
- Now the counter restart at 0 after reaching max.</p>
- <p>Own Id: OTP-3415</p>
- </item>
- <item>
- <p>Orber did not handle locate-requests correctly, i.e., not able to
- recognize the new internal representation of object references.</p>
- <p>Own Id: OTP-3414</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>It is now possible to start Orber as lightweight.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>It is now possible to create pseudo objects, i.e., not server objects.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>One new system exception introduced; 'BAD_QOS'.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>Orber now supports the types 'long long' and 'unsigned long long'</p>
- <p>Own Id: -</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Encoding typecode for complex exceptions (non-empty body) was not done
- correctly.</p>
- <p>Own Id: OTP-3390</p>
- </item>
- <item>
- <p>orber_iiop_pm crashed when it received an 'EXIT'. Now fixed.</p>
- <p>Own Id: OTP-3391</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.0.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Orber is now able to handle upgrade properly.</p>
- <p>Own Id: -</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Orber 3.0</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>It is now possible to use secure IIOP connections to and from Orber.
- Orber currently only supports security with the help of SSL and not SECIOP.</p>
- <p>Own Id: OTP-1510</p>
- </item>
- <item>
- <p>It is now possible to start Orber objects as supervisor children using
- Module_Interface:oe_create_link/2 or corba:create_link/4 as the start function.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>It is now possible to start a Orber object and be able to tell apart if it is in
- the process of being restarted or has permanently terminated. This is also the reason
- for introducing <c>objectkeys_gc_time</c> configuration parameter.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>The service CosEvent has been removed from orber and become its own application, called cosEvent.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>The service CosTransactions is now available as a separate application, called cosTransactions.</p>
- <p>Own Id: OTP-1741</p>
- </item>
- <item>
- <p>Three new system exceptions, 'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK'
- and 'INVALID_TRANSACTION', introduced. Required by the cosTransactions application.</p>
- <p>Own Id: -</p>
- </item>
- <item>
- <p>An configuration variable ip_address has been added, so it's possible
- to listen on a specific ip interface on a multi interface host.
- The value is the ip address as a string or a tuple of four integers,
- default value is all interfaces.</p>
- <p>Own Id: OTP-3294</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>set- and get-operations for the 'any'-module now behaves properly.</p>
- <p>Own Id: OTP-3355</p>
- </item>
- <item>
- <p>Orber can now handle IORs which contain more than one "Tagged Profile".</p>
- <p>Own Id: OTP-3266</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Incompatibilities</title>
- <list type="bulleted">
- <item>
- <p>CosEvent include paths have changed since it is now a separate application, called cosEvent.</p>
- </item>
- <item>
- <p>The internal representation of object references have changed. Orber do, however,
- recognize the old representation. But object references (created by Orber 2.2.2 or older)
- stored and used through several Orber upgrades may not be supported.</p>
- </item>
- <item>
- <p>The functions oe_create/2 and oe_create_link/2 now take an
- options list as its second argument. Orber still allow
- oe_create*(Env, {Type,RegName}) to be used, but may not in future releases.</p>
- </item>
- </list>
- </section>
- </section>
-</chapter>
-
diff --git a/lib/orber/doc/src/orber.xml b/lib/orber/doc/src/orber.xml
index da5fd05f98..05036667cc 100644
--- a/lib/orber/doc/src/orber.xml
+++ b/lib/orber/doc/src/orber.xml
@@ -558,7 +558,7 @@
<desc>
<p>This function installs all the necessary mnesia tables and
load default data in some of them. If one or more Orber tables
- already exists the installation fails. The function\011
+ already exists the installation fails. The function
<em>uninstall</em> may be used, if it is safe, i.e., no other
application is running Orber.</p>
<p>Preconditions:</p>
diff --git a/lib/orber/doc/src/part_notes.xml b/lib/orber/doc/src/part_notes.xml
index 0ff4453d8c..10b3a64373 100644
--- a/lib/orber/doc/src/part_notes.xml
+++ b/lib/orber/doc/src/part_notes.xml
@@ -30,8 +30,6 @@
<description>
<p>The Orber Application is an Erlang implementation of a CORBA Object
Request Broker.</p>
- <p>For information about older versions see
- <url href="part_notes_history_frame.html">release notes history</url>.</p>
</description>
<xi:include href="notes.xml"/>
</part>
diff --git a/lib/orber/doc/src/part_notes_history.xml b/lib/orber/doc/src/part_notes_history.xml
deleted file mode 100644
index 624865014e..0000000000
--- a/lib/orber/doc/src/part_notes_history.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part>
- <header>
- <copyright>
- <year>2004</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Orber Release Notes History</title>
- <prepared>Niclas Eklund</prepared>
- <docno></docno>
- <date>2004-09-15</date>
- <rev>1.0</rev>
- </header>
- <description>
- <p>The Orber Application is an Erlang implementation of a CORBA Object
- Request Broker.</p>
- </description>
- <include file="notes_history"></include>
-</part>
-
diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk
index 8ccdc9792c..ccba631fb5 100644
--- a/lib/orber/vsn.mk
+++ b/lib/orber/vsn.mk
@@ -1,7 +1,10 @@
-ORBER_VSN = 3.6.14
+ORBER_VSN = 3.6.15
-TICKETS = OTP-8201
+TICKETS = OTP-8353 \
+ OTP-8354
+
+TICKETS_3.6.14 = OTP-8201
TICKETS_3.6.13 = OTP-7987
diff --git a/lib/percept/src/egd.erl b/lib/percept/src/egd.erl
index 4becfef19b..7972fde597 100644
--- a/lib/percept/src/egd.erl
+++ b/lib/percept/src/egd.erl
@@ -128,13 +128,13 @@ line(Image, P1, P2, Color) ->
%% @spec color( Value | Name ) -> color()
%% where
-%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()}
-%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua
+%% Value = {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()}
+%% Name = black | silver | gray | white | maroon | red | purple | fuchia | green | lime | olive | yellow | navy | blue | teal | aqua
%% @doc Creates a color reference.
-spec(color/1 :: (
- Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) ->
- color()).
+ Value :: {byte(), byte(), byte()} | {byte(), byte(), byte(), byte()} | atom()) ->
+ color()).
color(Color) ->
egd_primitives:color(Color).
diff --git a/lib/percept/src/egd_font.erl b/lib/percept/src/egd_font.erl
index 2b2a89a0a9..5f0d56dd90 100644
--- a/lib/percept/src/egd_font.erl
+++ b/lib/percept/src/egd_font.erl
@@ -131,18 +131,18 @@ parse_glyph({Code,W,H,X0,Y0,Xm,Offset}, Bitmasks) ->
render_glyph(W, H, X0, Y0, Xm, Bitmask) ->
render_glyph(W,{0,H},X0,Y0,Xm,Bitmask, []).
render_glyph(_W, {H,H}, _X0, _Y0, _Xm, _Bitmask, Out) -> Out;
-render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask, LSs) ->
+render_glyph(W, {Hi,H}, X0, Y0,Xm, Bitmask , LSs) ->
N = ((W+7) div 8),
O = N*Hi,
<<_:O/binary, Submask/binary>> = Bitmask,
- LS = render_glyph_horizontal(
+ LS = render_glyph_horizontal(
Submask, % line glyph bitmask
{down, W - 1}, % loop state
W - 1, % Width
[]), % Linespans
render_glyph(W,{Hi+1,H},X0,Y0,Xm, Bitmask, [LS|LSs]).
-render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) ->
+render_glyph_horizontal(Value, {Pr, Px}, 0, Spans) ->
Cr = bit_spin(Value, 0),
case {Pr,Cr} of
{up , up } -> % closure of interval since its last
@@ -173,4 +173,3 @@ bit_spin(Value, Cx) ->
1 -> up;
0 -> down
end.
-
diff --git a/lib/percept/src/egd_png.erl b/lib/percept/src/egd_png.erl
index 3a0aaeef31..3a0aaeef31 100755..100644
--- a/lib/percept/src/egd_png.erl
+++ b/lib/percept/src/egd_png.erl
diff --git a/lib/percept/src/egd_primitives.erl b/lib/percept/src/egd_primitives.erl
index 245e0d48e2..77c600279f 100644
--- a/lib/percept/src/egd_primitives.erl
+++ b/lib/percept/src/egd_primitives.erl
@@ -28,6 +28,7 @@
pixel/3,
polygon/3,
line/4,
+ line/5,
arc/4,
arc/5,
rectangle/4,
@@ -50,7 +51,6 @@
-include("egd.hrl").
-
%% API info
info(I) ->
W = I#image.width, H = I#image.height,
@@ -75,13 +75,22 @@ object_info(O) ->
%% interface functions
line(I, Sp, Ep, Color) ->
- I#image{objects = [
+ I#image{ objects = [
#image_object{
type = line,
points = [Sp, Ep],
span = span([Sp, Ep]),
color = Color} | I#image.objects]}.
+line(I, Sp, Ep, Stroke, Color) ->
+ I#image{ objects = [
+ #image_object{
+ type = line,
+ points = [Sp, Ep],
+ span = span([Sp, Ep]),
+ internals = Stroke,
+ color = Color } | I#image.objects]}.
+
arc(I, {Sx,Sy} = Sp, {Ex,Ey} = Ep, Color) ->
X = Ex - Sx,
Y = Ey - Sy,
@@ -162,8 +171,6 @@ create(W, H) ->
#image{ width = W, height = H}.
-%color({crayon, Color}) -> rgba_byte2float(name_to_color({crayon, Color, 255}));
-%color({crayon, Color, A}) -> rgba_byte2float(name_to_color({crayon, Color, A}));
color(Color) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, 255}));
color({Color, A}) when is_atom(Color) -> rgba_byte2float(name_to_color({Color, A}));
color({R,G,B}) -> rgba_byte2float({R,G,B, 255});
@@ -314,129 +321,6 @@ name_to_color({ slategray, A}) -> { 112, 128, 144, A};
name_to_color({ dimgray, A}) -> { 105, 105, 105, A};
name_to_color({ darkslategray, A}) -> { 47, 79, 79, A}.
-%% Crayons
-%name_to_color({crayon, mahogany, A}) -> { 205, 74, 74, A};
-%name_to_color({crayon, 'fuzzy wuzzy brown', A}) -> { 204, 102, 102, A};
-%name_to_color({crayon, chestnut, A}) -> { 188, 93, 88, A};
-%name_to_color({crayon, 'red orange', A}) -> { 255, 83, 73, A};
-%name_to_color({crayon, 'sunset orange', A}) -> { 253, 94, 83, A};
-%name_to_color({crayon, bittersweet, A}) -> { 253, 124, 110, A};
-%name_to_color({crayon, melon, A}) -> { 253, 188, 180, A};
-%name_to_color({crayon, 'outrageous orange', A}) -> { 255, 110, 74, A};
-%name_to_color({crayon, 'vivid tangerine', A}) -> { 255, 160, 137, A};
-%name_to_color({crayon, 'burnt sienna', A}) -> { 234, 126, 93, A};
-%name_to_color({crayon, brown, A}) -> { 180, 103, 77, A};
-%name_to_color({crayon, sepia, A}) -> { 165, 105, 79, A};
-%name_to_color({crayon, orange, A}) -> { 255, 117, 56, A};
-%name_to_color({crayon, 'burnt orange', A}) -> { 255, 127, 73, A};
-%name_to_color({crayon, copper, A}) -> { 221, 148, 117, A};
-%name_to_color({crayon, 'mango tango', A}) -> { 255, 130, 67, A};
-%name_to_color({crayon, 'atomic tangerine', A}) -> { 255, 164, 116, A};
-%name_to_color({crayon, beaver, A}) -> { 159, 129, 112, A};
-%name_to_color({crayon, 'antique brass', A}) -> { 205, 149, 117, A};
-%name_to_color({crayon, 'desert sand', A}) -> { 239, 205, 184, A};
-%name_to_color({crayon, 'raw sienna', A}) -> { 214, 138, 89, A};
-%name_to_color({crayon, tumbleweed, A}) -> { 222, 170, 136, A};
-%name_to_color({crayon, tan, A}) -> { 250, 167, 108, A};
-%name_to_color({crayon, peach, A}) -> { 255, 207, 171, A};
-%name_to_color({crayon, 'macaroni and cheese', A}) -> { 255, 189, 136, A};
-%name_to_color({crayon, apricot, A}) -> { 253, 217, 181, A};
-%name_to_color({crayon, 'neon carrot', A}) -> { 255, 163, 67, A};
-%name_to_color({crayon, almond, A}) -> { 239, 219, 197, A};
-%name_to_color({crayon, 'yellow orange', A}) -> { 255, 182, 83, A};
-%name_to_color({crayon, gold, A}) -> { 231, 198, 151, A};
-%name_to_color({crayon, shadow, A}) -> { 138, 121, 93, A};
-%name_to_color({crayon, 'banana mania', A}) -> { 250, 231, 181, A};
-%name_to_color({crayon, sunglow, A}) -> { 255, 207, 72, A};
-%name_to_color({crayon, goldenrod, A}) -> { 252, 217, 117, A};
-%name_to_color({crayon, dandelion, A}) -> { 253, 219, 109, A};
-%name_to_color({crayon, yellow, A}) -> { 252, 232, 131, A};
-%name_to_color({crayon, 'green yellow', A}) -> { 240, 232, 145, A};
-%name_to_color({crayon, 'spring green', A}) -> { 236, 234, 190, A};
-%name_to_color({crayon, 'olive green', A}) -> { 186, 184, 108, A};
-%name_to_color({crayon, 'laser lemon', A}) -> { 253, 252, 116, A};
-%name_to_color({crayon, 'unmellow yellow', A}) -> { 253, 252, 116, A};
-%name_to_color({crayon, canary, A}) -> { 255, 255, 153, A};
-%name_to_color({crayon, 'yellow green', A}) -> { 197, 227, 132, A};
-%name_to_color({crayon, 'inch worm', A}) -> { 178, 236, 93, A};
-%name_to_color({crayon, asparagus, A}) -> { 135, 169, 107, A};
-%name_to_color({crayon, 'granny smith apple', A}) -> { 168, 228, 160, A};
-%name_to_color({crayon, 'electric lime', A}) -> { 29, 249, 20, A};
-%name_to_color({crayon, 'screamin green', A}) -> { 118, 255, 122, A};
-%name_to_color({crayon, fern, A}) -> { 113, 188, 120, A};
-%name_to_color({crayon, 'forest green', A}) -> { 109, 174, 129, A};
-%name_to_color({crayon, 'sea green', A}) -> { 159, 226, 191, A};
-%name_to_color({crayon, green, A}) -> { 28, 172, 120, A};
-%name_to_color({crayon, 'mountain meadow', A}) -> { 48, 186, 143, A};
-%name_to_color({crayon, shamrock, A}) -> { 69, 206, 162, A};
-%name_to_color({crayon, 'jungle green', A}) -> { 59, 176, 143, A};
-%name_to_color({crayon, 'caribbean green', A}) -> { 28, 211, 162, A};
-%name_to_color({crayon, 'tropical rain forest', A}) -> { 23, 128, 109, A};
-%name_to_color({crayon, 'pine green', A}) -> { 21, 128, 120, A};
-%name_to_color({crayon, 'robin egg blue', A}) -> { 31, 206, 203, A};
-%name_to_color({crayon, aquamarine, A}) -> { 120, 219, 226, A};
-%name_to_color({crayon, 'turquoise blue', A}) -> { 119, 221, 231, A};
-%name_to_color({crayon, 'sky blue', A}) -> { 128, 218, 235, A};
-%name_to_color({crayon, 'outer space', A}) -> { 65, 74, 76, A};
-%name_to_color({crayon, 'blue green', A}) -> { 25, 158, 189, A};
-%name_to_color({crayon, 'pacific blue', A}) -> { 28, 169, 201, A};
-%name_to_color({crayon, cerulean, A}) -> { 29, 172, 214, A};
-%name_to_color({crayon, cornflower, A}) -> { 154, 206, 235, A};
-%name_to_color({crayon, 'midnight blue', A}) -> { 26, 72, 118, A};
-%name_to_color({crayon, 'navy blue', A}) -> { 25, 116, 210, A};
-%name_to_color({crayon, denim, A}) -> { 43, 108, 196, A};
-%name_to_color({crayon, blue, A}) -> { 31, 117, 254, A};
-%name_to_color({crayon, periwinkle, A}) -> { 197, 208, 230, A};
-%name_to_color({crayon, 'cadet blue', A}) -> { 176, 183, 198, A};
-%name_to_color({crayon, indigo, A}) -> { 93, 118, 203, A};
-%name_to_color({crayon, 'wild blue yonder', A}) -> { 162, 173, 208, A};
-%name_to_color({crayon, manatee, A}) -> { 151, 154, 170, A};
-%name_to_color({crayon, 'blue bell', A}) -> { 173, 173, 214, A};
-%name_to_color({crayon, 'blue violet', A}) -> { 115, 102, 189, A};
-%name_to_color({crayon, 'purple heart', A}) -> { 116, 66, 200, A};
-%name_to_color({crayon, 'royal purple', A}) -> { 120, 81, 169, A};
-%name_to_color({crayon, 'purple mountains majesty', A}) -> { 157, 129, 186, A};
-%name_to_color({crayon, violet, A}) -> { 146, 110, 174, A};
-%name_to_color({crayon, wisteria, A}) -> { 205, 164, 222, A};
-%name_to_color({crayon, 'vivid violet', A}) -> { 143, 80, 157, A};
-%name_to_color({crayon, fuchsia, A}) -> { 195, 100, 197, A};
-%name_to_color({crayon, 'shocking pink', A}) -> { 251, 126, 253, A};
-%name_to_color({crayon, 'pink flamingo', A}) -> { 252, 116, 253, A};
-%name_to_color({crayon, plum, A}) -> { 142, 69, 133, A};
-%name_to_color({crayon, 'hot magenta', A}) -> { 255, 29, 206, A};
-%name_to_color({crayon, 'purple pizzazz', A}) -> { 255, 29, 206, A};
-%name_to_color({crayon, 'razzle dazzle rose', A}) -> { 255, 72, 208, A};
-%name_to_color({crayon, orchid, A}) -> { 230, 168, 215, A};
-%name_to_color({crayon, 'red violet', A}) -> { 192, 68, 143, A};
-%name_to_color({crayon, eggplant, A}) -> { 110, 81, 96, A};
-%name_to_color({crayon, cerise, A}) -> { 221, 68, 146, A};
-%name_to_color({crayon, 'wild strawberry', A}) -> { 255, 67, 164, A};
-%name_to_color({crayon, magenta, A}) -> { 246, 100, 175, A};
-%name_to_color({crayon, lavender, A}) -> { 252, 180, 213, A};
-%name_to_color({crayon, 'cotton candy', A}) -> { 255, 188, 217, A};
-%name_to_color({crayon, 'violet red', A}) -> { 247, 83, 148, A};
-%name_to_color({crayon, 'carnation pink', A}) -> { 255, 170, 204, A};
-%name_to_color({crayon, razzmatazz, A}) -> { 227, 37, 107, A};
-%name_to_color({crayon, 'piggy pink', A}) -> { 253, 215, 228, A};
-%name_to_color({crayon, 'jazzberry jam', A}) -> { 202, 55, 103, A};
-%name_to_color({crayon, blush, A}) -> { 222, 93, 131, A};
-%name_to_color({crayon, 'tickle me pink', A}) -> { 252, 137, 172, A};
-%name_to_color({crayon, 'pink sherbet', A}) -> { 247, 128, 161, A};
-%name_to_color({crayon, maroon, A}) -> { 200, 56, 90, A};
-%name_to_color({crayon, red, A}) -> { 238, 32, 77, A};
-%name_to_color({crayon, 'radical red', A}) -> { 255, 73, 108, A};
-%name_to_color({crayon, mauvelous, A}) -> { 239, 152, 170, A};
-%name_to_color({crayon, 'wild watermelon', A}) -> { 252, 108, 133, A};
-%name_to_color({crayon, scarlet, A}) -> { 252, 40, 71, A};
-%name_to_color({crayon, salmon, A}) -> { 255, 155, 170, A};
-%name_to_color({crayon, 'brick red', A}) -> { 203, 65, 84, A};
-%name_to_color({crayon, white, A}) -> { 237, 237, 237, A};
-%name_to_color({crayon, timberwolf, A}) -> { 219, 215, 210, A};
-%name_to_color({crayon, silver, A}) -> { 205, 197, 194, A};
-%name_to_color({crayon, gray, A}) -> { 149, 145, 140, A};
-%name_to_color({crayon, black, A}) -> { 35, 35, 35, A}.
-
-
text(I, {Xs,Ys} = Sp, Font, Text, Color) ->
{FW,FH} = egd_font:size(Font),
Length = length(Text),
diff --git a/lib/percept/src/egd_render.erl b/lib/percept/src/egd_render.erl
index f5e32c2a0f..cea9d2d926 100644
--- a/lib/percept/src/egd_render.erl
+++ b/lib/percept/src/egd_render.erl
@@ -35,7 +35,7 @@ binary(Image, Type) ->
parallel_binary(precompile(Image),Type).
parallel_binary(Image = #image{ height = Height },Type) ->
- case lists:min([erlang:system_info(schedulers), Height]) of
+ case erlang:min(erlang:system_info(schedulers), Height) of
1 ->
% if the height or the number of schedulers is 1
% do the scanlines in this process.
@@ -120,27 +120,15 @@ receive_binaries(H, Bins) when H > 0 ->
scanline(Y, Os, {_,_,Width,_}=LSB, Type) ->
- OLSs = parse_objects_on_line(Y-1, Width, Os),
- URLSs = resulting_line_spans([LSB|OLSs],Type),
-
- % FIXME: Can we keep the list sorted instead of sorting it?
- % sort descending
- RLSs = lists:reverse(URLSs),
-
- resulting_scanline(RLSs,Width).
-
-resulting_scanline(RLSs, Width) -> resulting_scanline(RLSs, Width, []).
-resulting_scanline([], _, Scanlines) -> Scanlines;
-resulting_scanline([{_,Xl, Xr, C} | RLSs], Width, Scanlines) ->
- {R,G,B,_} = rgb_float2byte(C),
- Scanline = lists:duplicate(trunc(Xr - Xl + 1), <<R:8,G:8,B:8>>),
- resulting_scanline(RLSs, Width, [Scanline|Scanlines]).
+ OLSs = parse_objects_on_line(Y-1, Width, Os),
+ RLSs = resulting_line_spans([LSB|OLSs],Type),
+ [ lists:duplicate(Xr - Xl + 1, <<(trunc(R*255)):8,(trunc(G*255)):8,(trunc(B*255)):8>>) || {_,Xl, Xr, {R,G,B,_}} <- RLSs ].
resulting_line_spans(LSs,Type) ->
%% Build a list of "transitions" from left to right.
Trans = line_spans_to_trans(LSs),
%% Convert list of "transitions" to linespans.
- trans_to_line_spans(Trans,Type).
+ trans_to_line_spans(Trans,Type).
line_spans_to_trans(LSs) ->
line_spans_to_trans(LSs,[],0).
@@ -194,19 +182,14 @@ color([{_,C}|_],opaque) -> C;
color(Layers,alpha) -> color1({0,0,0,0},Layers).
color1(Color,[]) -> Color;
-color1(Color,[{_,C}|Layers]) -> color1(blend(Color,C),Layers).
-
-blend(C1,C2) -> alpha_blend(C1,C2).
+color1(Color,[{_,C}|Layers]) -> color1(alpha_blend(Color,C),Layers).
modify_layers(Layers,[]) -> Layers;
-modify_layers(Layers,[{{_,Z,Op},C}|Trans]) ->
- modify_layers(case Op of
- start ->
- add_layer(Layers,Z,C);
- stop ->
- remove_layer(Layers,Z,C)
- end,
- Trans).
+modify_layers(Layers,[{{_,Z,start},C}|Trans]) ->
+ modify_layers(add_layer(Layers, Z, C), Trans);
+modify_layers(Layers,[{{_,Z,stop },C}|Trans]) ->
+ modify_layers(remove_layer(Layers, Z, C), Trans).
+
add_layer([{Z1,_}=H|Layers],Z,C) when Z1 > Z ->
[H|add_layer(Layers,Z,C)];
@@ -216,7 +199,7 @@ add_layer(Layers,Z,C) ->
remove_layer(Layers,Z,C) ->
Layers -- [{Z,C}].
-alpha_blend({R1,G1,B1,A1}, {R2,G2,B2,A2}) ->
+alpha_blend({R1,G1,B1,A1}, {R2,G2,B2,A2}) when is_float(A1), is_float(A2)->
Beta = A2*(1.0 - A1),
A = A1 + Beta,
R = R1*A1 + R2*Beta,
@@ -232,7 +215,7 @@ parse_objects_on_line(Y, Z, Width, [O|Os], Out) ->
false ->
parse_objects_on_line(Y, Z + 1, Width, Os, Out);
true ->
- OLs = object_line_data(Y, Z, O),
+ OLs = object_line_data(Y, Z, O),
TOLs = trim_object_line_data(OLs, Width),
parse_objects_on_line(Y, Z + 1, Width, Os, [TOLs|Out])
end.
@@ -240,15 +223,13 @@ parse_objects_on_line(Y, Z, Width, [O|Os], Out) ->
trim_object_line_data(OLs, Width) ->
trim_object_line_data(OLs, Width, []).
trim_object_line_data([], _, Out) -> Out;
+
+trim_object_line_data([{_, Xl, _, _}|OLs], Width, Out) when Xl > Width ->
+ trim_object_line_data(OLs, Width, Out);
+trim_object_line_data([{_, _, Xr, _}|OLs], Width, Out) when Xr < 0 ->
+ trim_object_line_data(OLs, Width, Out);
trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) ->
- if
- Xl > Width ->
- trim_object_line_data(OLs, Width, Out);
- Xr < 0 ->
- trim_object_line_data(OLs, Width, Out);
- true ->
- trim_object_line_data(OLs, Width, [{Z, lists:max([0,Xl]), lists:min([Xr,Width]), C}|Out])
- end.
+ trim_object_line_data(OLs, Width, [{Z, erlang:max(0,Xl), erlang:min(Xr,Width), C}|Out]).
% object_line_data
% In:
@@ -264,7 +245,8 @@ trim_object_line_data([{Z, Xl, Xr, C}|OLs], Width, Out) ->
% Calculate the length (start and finish index) of an objects horizontal
% line given the height index.
-object_line_data(Y, Z, Object) -> object_line_data(Y, Z, Object, Object#image_object.type).
+object_line_data(Y, Z, Object) ->
+ object_line_data(Y, Z, Object, Object#image_object.type).
object_line_data(Y, Z, #image_object{ span = {X0, Y0, X1, Y1}, color = C}, rectangle) ->
if
Y0 =:= Y ; Y1 =:= Y ->
@@ -277,70 +259,43 @@ object_line_data(Y, Z, #image_object{ span = {X0, Y0, X1, Y1}, color = C}, recta
object_line_data(_Y, Z, #image_object{ span = {X0, _, X1, _}, color = C}, filled_rectangle) ->
[{Z, X0, X1, C}];
-object_line_data(Y, Z, #image_object{ span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) ->
+object_line_data(Y, Z, #image_object{ internals={Xr,Yr,Yr2}, span = {X0,Y0,X1,Y1}, color = C}, filled_ellipse) ->
if
- X1 - X0 == 0 -> % if the width is exactly one pixel
- [{Z, X1, X0, C}];
- X1 - X0 < 0 -> throw(bad_ellipse_width);
- Y1 - Y0 == 0 -> % Height exactly one pixel, get width
+ X1 - X0 == 0; Y1 - Y0 == 0 ->
[{Z, X0, X1, C}];
true ->
- Xr = (X1 - X0)/2,
- Yr = (Y1 - Y0)/2,
- Yo = trunc(Y - Y0 - Yr),
+ Yo = trunc(Y - Y0 - Yr),
Yo2 = Yo*Yo,
- Yr2 = Yr*Yr,
- Xo = math:sqrt((1 - Yo2/Yr2))*Xr,
+ Xo = math:sqrt((1 - Yo2/Yr2))*Xr,
[{Z, round(X0 - Xo + Xr), round(X0 + Xo + Xr), C}]
end;
object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, filled_triangle) ->
- case lists:keysearch(Y, 1, Is) of
- {value, {Y, Xl, Xr}} -> [{Z, Xl, Xr, C}];
+ case lists:keyfind(Y, 1, Is) of
+ {Y, Xl, Xr} -> [{Z, Xl, Xr, C}];
false -> []
end;
object_line_data(Y, Z, #image_object{ intervals = Is, color = C}, line) ->
case dict:find(Y, Is) of
- %{ok, {Xl, Xr}} -> [{Z, Xl, Xr, C}];
{ok, Ls} -> [{Z, Xl, Xr, C}||{Xl,Xr} <- Ls];
_ -> []
end;
-object_line_data(Y, Z, O, polygon) ->
- Is = lists:filter(
- fun({Yp,_,_}) ->
- if Yp == Y -> true; true -> false end
- end, O#image_object.intervals),
- [ {Z, Xl, Xr, O#image_object.color} || {_, Xl, Xr} <- Is];
-
-object_line_data(Y, Z, #image_object{ color = C, intervals = Is }, text_horizontal) ->
- % FIXME: optimize!
- lists:foldl(
- fun ({Yg,Xl,Xr}, Out) ->
- if
- Yg == Y ->
- [{Z, Xl, Xr, C}|Out];
- true ->
- Out
- end
- end, [], Is);
+object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, polygon) ->
+ [{Z, Xl, Xr, C} || {Yp, Xl, Xr} <- Is, Yp =:= Y];
+
+object_line_data(Y, Z, #image_object{ color = C, intervals = Is}, text_horizontal) ->
+ [{Z, Xl, Xr, C} || {Yg, Xl, Xr} <- Is, Yg =:= Y];
+
object_line_data(_, Z, #image_object{ span = {X0,_,X1,_}, color = C}, _) ->
- % faked
[{Z, X0, X1, C}].
-is_object_on_line(Y, Object) ->
- is_object_bounds_on_line(Y, Object#image_object.span).
+is_object_on_line(Y, #image_object{ span = Span }) ->
+ is_object_bounds_on_line(Y, Span).
-is_object_bounds_on_line(Y, {_,Y0,_,Y1}) ->
- if
- Y < Y0 -> false;
- Y > Y1 -> false;
- true -> true
- end.
-
-rgb_float2byte({R,G,B,A}) ->
- {trunc(R*255), trunc(G*255), trunc(B*255), trunc(A*255)}.
+is_object_bounds_on_line(Y, {_,Y0,_,Y1}) when Y < Y0 ; Y > Y1 -> false;
+is_object_bounds_on_line(_, _) -> true.
%%% primitives to line_spans
@@ -360,6 +315,12 @@ precompile_objects([O = #image_object{ type = filled_triangle, points = [P0,P1,P
precompile_objects([O = #image_object{ type = polygon, points = Pts } | Os], Out) ->
precompile_objects(Os, [O#image_object{ intervals = polygon_ls(Pts) } | Out]);
+
+precompile_objects([O = #image_object{ type = filled_ellipse, span = {X0,Y0,X1,Y1} } | Os], Out) ->
+ Xr = (X1 - X0)/2,
+ Yr = (Y1 - Y0)/2,
+ Yr2 = Yr*Yr,
+ precompile_objects(Os, [ O#image_object{ internals={Xr,Yr,Yr2} } | Out]);
precompile_objects([O = #image_object{ type = arc, points = [P0,P1], internals = D }| Os], Out) ->
Es = egd_primitives:arc_to_edges(P0, P1, D),
@@ -579,13 +540,7 @@ line_ls({Xi0, Yi0},{Xi1,Yi1}) ->
true -> 1;
false -> -1
end,
- case Steep of
- false ->
- line_ls_step_not_steep({X0, X1},Y0, DX, DY, Ystep, Error, X0, []);
- true ->
- line_ls_step_steep({X0, X1},Y0, DX, DY, Ystep, Error, X0, [])
- end.
-
+ line_ls_step(X0, X1,Y0, DX, DY, Ystep, Error, X0, Steep, []).
%% line_ls_step_(not)_steep
%% In:
@@ -594,27 +549,17 @@ line_ls({Xi0, Yi0},{Xi1,Yi1}) ->
%% Purpose:
%% Produce an line_interval for each Yi (Y index)
-% Iterating the X-axis
-
-line_ls_step_not_steep({X,X1},Y,Dx,Dy,Ys,E, X0, LSs) when X < X1 ->
- case E >= 0 of
- true ->
- line_ls_step_not_steep({X+1,X1},Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X+1,[{Y,X0,X}|LSs]);
- false ->
- line_ls_step_not_steep({X+1,X1},Y,Dx,Dy,Ys, E + Dy, X0, LSs)
- end;
-line_ls_step_not_steep({X,_},Y,_Dx,_Dy,_Ystep,_E,X0,LSs) ->
- [{Y,X0,X}|LSs].
-
-% Iterating the Y-axis
-line_ls_step_steep({X,X1},Y,Dx,Dy,Ystep,E, X0, LSs) when X =< X1 ->
- case E >= 0 of
- true ->
- line_ls_step_steep({X + 1,X1},Y+Ystep,Dx,Dy,Ystep,E - Dx + Dy,X,[{X,Y,Y}|LSs]);
- false ->
- line_ls_step_steep({X + 1,X1},Y,Dx,Dy,Ystep,E + Dy,X0, [{X,Y,Y}|LSs])
- end;
-line_ls_step_steep({_X,_},_Y,_Dx,_Dy,_Ystep,_E,_X0,LSs) ->
+line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1, E >= 0 ->
+ line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X+1, Steep, [{Y,X0,X}|LSs]);
+line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, false = Steep, LSs) when X < X1 ->
+ line_ls_step(X+1,X1,Y,Dx,Dy,Ys, E + Dy, X0, Steep, LSs);
+line_ls_step(X, _X1, Y, _Dx, _Dy, _Ys, _E, X0, false, LSs) ->
+ [{Y,X0,X}|LSs];
+line_ls_step(X, X1, Y, Dx, Dy, Ys, E, _X0, true = Steep, LSs) when X =< X1, E >= 0 ->
+ line_ls_step(X+1,X1,Y+Ys,Dx,Dy,Ys, E - Dx + Dy, X, Steep, [{X,Y,Y}|LSs]);
+line_ls_step(X, X1, Y, Dx, Dy, Ys, E, X0, true = Steep, LSs) when X =< X1 ->
+ line_ls_step(X+1,X1,Y,Dx,Dy,Ys,E + Dy, X0, Steep, [{X,Y,Y}|LSs]);
+line_ls_step(_X,_,_Y,_Dx,_Dy,_Ys,_E,_X0,_,LSs) ->
LSs.
% Text
@@ -707,3 +652,4 @@ eps_header(W,H) ->
eps_footer() ->
"%%EOF\n".
+
diff --git a/lib/percept/test/egd_SUITE.erl b/lib/percept/test/egd_SUITE.erl
index 603ad628d3..a2595400dd 100644
--- a/lib/percept/test/egd_SUITE.erl
+++ b/lib/percept/test/egd_SUITE.erl
@@ -29,6 +29,7 @@
-export([
image_create_and_destroy/1,
image_shape/1,
+ image_primitives/1,
image_colors/1,
image_font/1,
image_png_compliant/1
@@ -38,8 +39,7 @@
-define(default_timeout, ?t:minutes(1)).
init_per_suite(Config) when is_list(Config) ->
- {A1,A2,A3} = now(),
- random:seed(A1, A2, A3),
+ random:seed(now()),
Config.
end_per_suite(Config) when is_list(Config) ->
@@ -59,6 +59,7 @@ all(suite) ->
[
image_create_and_destroy,
image_shape,
+ image_primitives,
image_colors,
image_font,
image_png_compliant
@@ -145,7 +146,43 @@ image_shape(Config) when is_list(Config) ->
?line ok = egd:destroy(Im),
erase(image_size),
ok.
-
+
+image_primitives(suite) ->
+ [];
+image_primitives(doc) ->
+ ["Image shape api test."];
+image_primitives(Config) when is_list(Config) ->
+ {W,H} = get_size(?config(max_size, Config)),
+ put(image_size, {W,H}),
+
+ ?line Im0 = egd_primitives:create(W, H),
+ ?line Fgc = egd:color({25,25,255}),
+ ?line Bgc = egd:color({0,250,25}),
+
+ ?line Im1 = lists:foldl(fun
+ ({Function, Arguments}, Im) ->
+ ?line erlang:apply(egd_primitives, Function, [Im|Arguments])
+ end, Im0,
+ [{Fs, [get_point(), get_point(), Bgc]} || Fs <- [line, rectangle, filledEllipse, arc]] ++
+ [{pixel, [get_point(), Bgc]},
+ {filledTriangle, [get_point(), get_point(), get_point(), Bgc]}]),
+
+ Pt1 = get_point(),
+ Pt2 = get_point(),
+
+ ?line Im2 = egd_primitives:filledRectangle(Im1, Pt1, Pt2, Fgc),
+
+ ?line Bitmap = egd_render:binary(Im2, opaque),
+
+ ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt2, Fgc),
+ ?line ok = bitmap_point_has_color(Bitmap, {W,H}, Pt1, Fgc),
+
+ erase(image_size),
+ ok.
+
+
+
+
image_font(suite) ->
[];
image_font(doc) ->
diff --git a/lib/public_key/doc/src/cert_records.xml b/lib/public_key/doc/src/cert_records.xml
index 8fb4ea5fd0..8cfe57f670 100644
--- a/lib/public_key/doc/src/cert_records.xml
+++ b/lib/public_key/doc/src/cert_records.xml
@@ -41,10 +41,18 @@
</p>
<p>Use the following include directive to get access to the
- records and constant macros described in the following sections.</p>
+ records and constant macros (OIDs) described in the following sections.</p>
<code> -include_lib("public_key/include/public_key.hrl"). </code>
+ <p>The used specification is available in <c>OTP-PKIX.asn1</c>,
+ which is an amelioration of
+ the <c>PKIX1Explicit88.asn1</c>, <c>PKIX1Implicit88.asn1</c>
+ and <c>PKIX1Algorithms88.asn1</c> modules.
+ You find all these modules in the <c>asn1</c> subdirectory
+ of the application <c>public_key</c>.
+ </p>
+
<section>
<title>Common Data Types</title>
@@ -148,8 +156,7 @@ oid names see table below. Ex: ?'id-dsa-with-sha1'</p>
}.
</code>
-<p><c>id_attributes() = ?oid_name_as_erlang_atom</c>
-for available oid names see table below. Ex: ?'id-at-name'</p>
+<p><c>id_attributes() </c></p>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
@@ -231,8 +238,7 @@ for available oid names see table below. Ex: ?'id-at-name'</p>
}.
</code>
-<p><c> id_public_key_algorithm() = ?oid_name_as_erlang_atom</c> for available
-oid names see table below. Ex: ?'id-dsa'</p>
+<p><c> id_public_key_algorithm() </c></p>
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
@@ -264,14 +270,11 @@ oid names see table below. Ex: ?'id-dsa'</p>
}.
</code>
-<p><c>id_extensions() = ?oid_name_as_erlang_atom</c> for
-available oid names see tables. Ex: ?'id-ce-authorityKeyIdentifier'<seealso
-marker="#StdCertExt">Standard Certificate Extensions</seealso>,
- <seealso
- marker="#PrivIntExt">Private Internet Extensions</seealso>, <seealso
- marker="#CRLCertExt">CRL Extensions</seealso> and
- <seealso
- marker="#CRLEntryExt">CRL Entry Extensions</seealso>.
+<p><c>id_extensions()</c>
+ <seealso marker="#StdCertExt">Standard Certificate Extensions</seealso>,
+ <seealso marker="#PrivIntExt">Private Internet Extensions</seealso>,
+ <seealso marker="#CRLCertExt">CRL Extensions</seealso> and
+ <seealso marker="#CRLEntryExt">CRL Entry Extensions</seealso>.
</p>
</section>
@@ -368,9 +371,8 @@ marker="#StdCertExt">Standard Certificate Extensions</seealso>,
decipherOnly
</c></p>
- <p><c> id_key_purpose() = ?oid_name_as_erlang_atom</c> for available
-oid names see table below. Ex: ?'id-kp-serverAuth'</p>
-
+ <p><c> id_key_purpose()</c></p>
+
<table>
<row>
<cell align="left" valign="middle">OID name</cell>
diff --git a/lib/ssh/doc/src/Makefile b/lib/ssh/doc/src/Makefile
index d2907a39d7..e02f04e7ad 100644
--- a/lib/ssh/doc/src/Makefile
+++ b/lib/ssh/doc/src/Makefile
@@ -53,8 +53,8 @@ XML_REF3_FILES = \
ssh_sftp.xml \
ssh_sftpd.xml \
-XML_PART_FILES = part_notes.xml part_notes_history.xml
-XML_CHAPTER_FILES = notes.xml notes_history.xml
+XML_PART_FILES = part_notes.xml
+XML_CHAPTER_FILES = notes.xml
BOOK_FILES = book.xml
@@ -70,8 +70,6 @@ EXTRA_FILES = \
$(XML_REF3_FILES:%.xml=$(HTMLDIR)/%.html) \
$(XML_CHAPTER_FILES:%.xml=$(HTMLDIR)/%.html)
-# notes_history.html \
-
MAN3_FILES = $(XML_REF3_FILES:%.xml=$(MAN3DIR)/%.3)
diff --git a/lib/ssh/doc/src/notes.xml b/lib/ssh/doc/src/notes.xml
index 54e0cf9059..ef49bb8b3d 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -29,6 +29,19 @@
<file>notes.xml</file>
</header>
+ <section><title>Ssh 1.1.8</title>
+
+ <section><title>Improvements and New Features</title>
+ <list>
+ <item>
+ <p>Old release notes removed.</p>
+ <p>Own Id: OTP-8356 Aux Id:</p>
+ </item>
+ </list>
+ </section>
+
+ </section>
+
<section><title>Ssh 1.1.7</title>
<section><title>Fixed Bugs and Malfunctions</title>
@@ -581,8 +594,6 @@
</list>
</section>
- <!-- p>For information about older versions see
- <url href="part_notes_history_frame.html">release notes history</url>.</p -->
</section>
</chapter>
diff --git a/lib/ssh/doc/src/notes_history.xml b/lib/ssh/doc/src/notes_history.xml
deleted file mode 100644
index bfebcd4bf4..0000000000
--- a/lib/ssh/doc/src/notes_history.xml
+++ /dev/null
@@ -1,737 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2009</year>
- <year>2009</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>SSH Release Notes History</title>
- <prepared></prepared>
- <responsible></responsible>
- <docno></docno>
- <approved></approved>
- <checked></checked>
- <date></date>
- <rev>A</rev>
- <file>notes_history.xml</file>
- </header>
-
- <section><title>Ssh 0.9.9.6</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Updated asn1 file due to change in the asn1 compiler.
- This has no semantical effect on the ssh application.</p>
- <p>
- Own Id: OTP-7246</p>
- </item>
- <item>
- <p>
- Allows for the option {fd, FD} in listen and connect
- calls. The option is passed on to gen_tcp:listen and
- gen_tcp:connect</p>
- <p>
- Own Id: OTP-7247</p>
- </item>
- </list>
- </section>
-</section>
-
- <section><title>Ssh 0.9.9.5</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- Putty version 0.60 sends ignore messages, which hanged
- the OTP ssh server.</p>
- <p>
- Own Id: OTP-7076</p>
- </item>
- <item>
- <p>
- ssh_cm hanged when connection was closed during
- handshake. (Triggered by putty 0.60 client.)</p>
- <p>
- Own Id: OTP-7089</p>
- </item>
- <item>
- <p>
- Fixed crash in server when receiving an empty ignore-msg.
- (From the putty 0.60 client.)</p>
- <p>
- Own Id: OTP-7135</p>
- </item>
- </list>
- </section>
-
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- Now uses the base 64 encode/decode function in stdlib.</p>
- <p>
- Own Id: OTP-6486</p>
- </item>
- <item>
- <p>
- Removed runtime dependency on asn1.</p>
- <p>
- Own Id: OTP-6570</p>
- </item>
- <item>
- <p>
- Documentation update of ssh.</p>
- <p>
- Own Id: OTP-7063 Aux Id: seq10789 </p>
- </item>
- <item>
- <p>
- Same listener is used for both sshd and sftpd. Previously
- the sftpd server had to be run on a separate port, now
- the sshd listener will start an sftpd server when an sftp
- client connects.</p>
- <p>
- Own Id: OTP-7090 Aux Id: seq10675 </p>
- </item>
- <item>
- <p>
- Kebord-interactive support, according to rfc 4256, has
- been added to the ssh client. Also the option
- <c>quiet_mode</c> has been added so that unwanted banners
- may be suppressed.</p>
- <p>
- Own Id: OTP-7106 Aux Id: seq10841 </p>
- </item>
- </list>
- </section>
-
- </section>
-
- <section><title>Ssh 0.9.9.4</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- [sftpd] - Root parameter now behaves as expected,
- instead of making sftpd malfunction.</p>
- <p>
- Own Id: OTP-7057 Aux Id: seq10830 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section><title>Ssh 0.9.9.3</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- The sftp-server could crash if a "ls" was done on the
- client, and a file was removed while ssh_sftpd:list_dir
- was reading the directory, an error code from
- read_file_info wasn't handled properly. This fix makes ls
- return an error code instead.</p>
- <p>
- Own Id: OTP-6854 Aux Id: seq10740 </p>
- </item>
- <item>
- <p>
- Fixed bugs in prompting in ssl_cli. Prompts like \003>
- were written as \300>. Also, newlines and returns was
- removed.</p>
- <p>
- Own Id: OTP-6917 Aux Id: seq10773 </p>
- </item>
- </list>
- </section>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- [sftpd] - New option "root" to set the root of the
- sftp-server and the callback module for file handling now
- has a state parameter.</p>
- <p>
- Own Id: OTP-7075 Aux Id: seq10675 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.9.2</title>
- <section>
- <title>Better error-handling in ssh_sshd:listen</title>
- <list type="bulleted">
- <item>
- <p>The caller was hanged when listening with ssh_sshd:listen
- (or ssh_sftpd:listen) on a port and IP already in use.
- Now an error is returned instead.</p>
- <p>Own Id: OTP-6727</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fix in ssh_sftpd</title>
- <list type="bulleted">
- <item>
- <p>Cd ../.. didn't work when connecting to a ssh_sftpd server.</p>
- <p>Own Id: OTP-6727</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.9.1</title>
-
- <section>
- <title>Minor Makefile changes</title>
- <list type="bulleted">
- <item>
- <p>Removed use of <c><![CDATA[erl_flags]]></c> from Makefile.</p>
- <p>Own Id: OTP-6689</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.9</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A race condition that could make the server crash if a
- client sent a SSH_MSG_USERAUTH_REQUEST packet immediately
- after its SSH_MSG_SERVICE_REQUEST, is removed.</p>
- <p>Own Id: OTP-6379 Aux Id: seq10523 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.8</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Corrected minor bugs and removed dead code found by
- dialyzer.</p>
- <p>Own Id: OTP-6524</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.7</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>[sftp] - The function ssh_sftp:make_symlink/3 was not
- fully implemented.</p>
- <p>Own Id: OTP-6446</p>
- </item>
- <item>
- <p>[ssh] - An internal value was, due to a bug, always set
- to undefined even when it was not, this could lead to
- connections being wrongly refused.</p>
- <p>Own Id: OTP-6450</p>
- </item>
- <item>
- <p>A pattern matching was missing "/binary" resulting in
- that the internal function ssh_xfer:decode_acl/2 did not
- work as expected.</p>
- <p>Own Id: OTP-6458</p>
- </item>
- <item>
- <p>[sftp] - read_link/2 did not return the documented value</p>
- <p>Own Id: OTP-6471</p>
- </item>
- <item>
- <p>Removed debugg printouts from ssh_cli.erl</p>
- <p>Own Id: OTP-6483</p>
- </item>
- <item>
- <p>[sftp, ssh] - The connection timeout was overridden by an
- internal gen_server default timeout.</p>
- <p>Own Id: OTP-6488 Aux Id: seq10569 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.6</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Removed debug printout from production code.</p>
- <p>Own Id: OTP-6348 Aux Id: seq10510 </p>
- </item>
- <item>
- <p>[sftpd] - When the sftp client ends the session the
- server will now behave correctly and not leave the client
- hanging.</p>
- <p>Own Id: OTP-6349 Aux Id: seq10510 </p>
- </item>
- <item>
- <p>[sftpd] - No longer used files were not closed until the
- session was ended.</p>
- <p>Own Id: OTP-6350 Aux Id: seq10514 </p>
- </item>
- <item>
- <p>[sftpd] - File rename requests sent by sftp version 3
- clients were not handled.</p>
- <p>Own Id: OTP-6352 Aux Id: seq10513 </p>
- </item>
- <item>
- <p>[sftpd] - Request that did not fit into one ssh message
- were not handled.</p>
- <p>Own Id: OTP-6353 Aux Id: seq10515 </p>
- </item>
- <item>
- <p>Removed error logging of auth method none, as this is not
- an error but rather a feature, that is used to get
- initial information from the server.</p>
- <p>Own Id: OTP-6414</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>[sftpd] - Added new option to specify a callback module
- for the sftpd-server file handling. The default callback
- module uses file and filelib.</p>
- <p>Own Id: OTP-6356 Aux Id: seq10519 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The data window in SSH wasn't resized in the ssh_cli
- receive data, this made the ssh_cli-server hang if more
- than 64K data was received at one time. The option
- tcp_nodelay was added, for nodelay in tcp connections.</p>
- <p>Own Id: OTP-6231</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.4</title>
-
- <section>
- <title>Reported Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Unnecessary explicit start of crypto application
- in ssh application. This has been removed. The
- app-file specifies that ssh depends on the crypto app.
- This is enough. See also the
- <seealso marker="ssh">ssh</seealso> module.</p>
- <p>Also changed some error reports to info reports.</p>
- <p>Own Id: OTP-6183</p>
- <p>Aux Id: Seq 10383</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Added way for cli to get peer name</p>
- <p>Own Id: OTP-6138</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.2</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Added some options to listen</p>
- <p>Own Id: OTP-6070</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.1</title>
- <section><title>Ssh 0.9.9.4</title>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- [sftpd] - Root parameter now behaves as expected,
- instead of making sftpd malfunction.</p>
- <p>
- Own Id: OTP-7057 Aux Id: seq10830 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section><title>Ssh 0.9.9.3</title>
-
- <section><title>Fixed Bugs and Malfunctions</title>
- <list>
- <item>
- <p>
- The sftp-server could crash if a "ls" was done on the
- client, and a file was removed while ssh_sftpd:list_dir
- was reading the directory, an error code from
- read_file_info wasn't handled properly. This fix makes ls
- return an error code instead.</p>
- <p>
- Own Id: OTP-6854 Aux Id: seq10740 </p>
- </item>
- <item>
- <p>
- Fixed bugs in prompting in ssl_cli. Prompts like \003>
- were written as \300>. Also, newlines and returns was
- removed.</p>
- <p>
- Own Id: OTP-6917 Aux Id: seq10773 </p>
- </item>
- </list>
- </section>
-
- <section><title>Improvements and New Features</title>
- <list>
- <item>
- <p>
- [sftpd] - New option "root" to set the root of the
- sftp-server and the callback module for file handling now
- has a state parameter.</p>
- <p>
- Own Id: OTP-7075 Aux Id: seq10675 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.9.2</title>
- <section>
- <title>Better error-handling in ssh_sshd:listen</title>
- <list type="bulleted">
- <item>
- <p>The caller was hanged when listening with ssh_sshd:listen
- (or ssh_sftpd:listen) on a port and IP already in use.
- Now an error is returned instead.</p>
- <p>Own Id: OTP-6727</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Fix in ssh_sftpd</title>
- <list type="bulleted">
- <item>
- <p>Cd ../.. didn't work when connecting to a ssh_sftpd server.</p>
- <p>Own Id: OTP-6727</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.9.1</title>
-
- <section>
- <title>Minor Makefile changes</title>
- <list type="bulleted">
- <item>
- <p>Removed use of <c><![CDATA[erl_flags]]></c> from Makefile.</p>
- <p>Own Id: OTP-6689</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.9</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>A race condition that could make the server crash if a
- client sent a SSH_MSG_USERAUTH_REQUEST packet immediately
- after its SSH_MSG_SERVICE_REQUEST, is removed.</p>
- <p>Own Id: OTP-6379 Aux Id: seq10523 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.8</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Corrected minor bugs and removed dead code found by
- dialyzer.</p>
- <p>Own Id: OTP-6524</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.7</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>[sftp] - The function ssh_sftp:make_symlink/3 was not
- fully implemented.</p>
- <p>Own Id: OTP-6446</p>
- </item>
- <item>
- <p>[ssh] - An internal value was, due to a bug, always set
- to undefined even when it was not, this could lead to
- connections being wrongly refused.</p>
- <p>Own Id: OTP-6450</p>
- </item>
- <item>
- <p>A pattern matching was missing "/binary" resulting in
- that the internal function ssh_xfer:decode_acl/2 did not
- work as expected.</p>
- <p>Own Id: OTP-6458</p>
- </item>
- <item>
- <p>[sftp] - read_link/2 did not return the documented value</p>
- <p>Own Id: OTP-6471</p>
- </item>
- <item>
- <p>Removed debugg printouts from ssh_cli.erl</p>
- <p>Own Id: OTP-6483</p>
- </item>
- <item>
- <p>[sftp, ssh] - The connection timeout was overridden by an
- internal gen_server default timeout.</p>
- <p>Own Id: OTP-6488 Aux Id: seq10569 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.6</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Removed debug printout from production code.</p>
- <p>Own Id: OTP-6348 Aux Id: seq10510 </p>
- </item>
- <item>
- <p>[sftpd] - When the sftp client ends the session the
- server will now behave correctly and not leave the client
- hanging.</p>
- <p>Own Id: OTP-6349 Aux Id: seq10510 </p>
- </item>
- <item>
- <p>[sftpd] - No longer used files were not closed until the
- session was ended.</p>
- <p>Own Id: OTP-6350 Aux Id: seq10514 </p>
- </item>
- <item>
- <p>[sftpd] - File rename requests sent by sftp version 3
- clients were not handled.</p>
- <p>Own Id: OTP-6352 Aux Id: seq10513 </p>
- </item>
- <item>
- <p>[sftpd] - Request that did not fit into one ssh message
- were not handled.</p>
- <p>Own Id: OTP-6353 Aux Id: seq10515 </p>
- </item>
- <item>
- <p>Removed error logging of auth method none, as this is not
- an error but rather a feature, that is used to get
- initial information from the server.</p>
- <p>Own Id: OTP-6414</p>
- </item>
- </list>
- </section>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>[sftpd] - Added new option to specify a callback module
- for the sftpd-server file handling. The default callback
- module uses file and filelib.</p>
- <p>Own Id: OTP-6356 Aux Id: seq10519 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>Ssh 0.9.5</title>
-
- <section>
- <title>Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>The data window in SSH wasn't resized in the ssh_cli
- receive data, this made the ssh_cli-server hang if more
- than 64K data was received at one time. The option
- tcp_nodelay was added, for nodelay in tcp connections.</p>
- <p>Own Id: OTP-6231</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.4</title>
-
- <section>
- <title>Reported Fixed Bugs and Malfunctions</title>
- <list type="bulleted">
- <item>
- <p>Unnecessary explicit start of crypto application
- in ssh application. This has been removed. The
- app-file specifies that ssh depends on the crypto app.
- This is enough. See also the
- <seealso marker="ssh">ssh</seealso> module.</p>
- <p>Also changed some error reports to info reports.</p>
- <p>Own Id: OTP-6183</p>
- <p>Aux Id: Seq 10383</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.3</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Added way for cli to get peer name</p>
- <p>Own Id: OTP-6138</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.2</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Added some options to listen</p>
- <p>Own Id: OTP-6070</p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9.1</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>Fixes in ssh_sftp, changes of timeout handling,
- expand_fun moved to io:setopts</p>
- <p>Own Id: OTP-5877 Aux Id: OTP-5781 </p>
- </item>
- </list>
- </section>
- </section>
-
- <section>
- <title>SSH 0.9</title>
-
- <section>
- <title>Improvements and New Features</title>
- <list type="bulleted">
- <item>
- <p>The previously undocumented and UNSUPPORTED <c><![CDATA[ssh]]></c>
- application has been updated and documented. This release
- of the <c><![CDATA[ssh]]></c> application is still considered to be a
- beta release and (if necessary) there could still be
- changes in its API before it reaches 1.0.</p>
- <p>Also, more cryptographic algorithms have been added to
- the <c><![CDATA[crypto]]></c> application.</p>
- <p>*** POTENTIAL INCOMPATIBILITY ***</p>
- <p>Own Id: OTP-5631</p>
- </item>
- </list>
- </section>
- </section>
- </section>
-
-</chapter>
-
-
diff --git a/lib/ssh/doc/src/part_notes.xml b/lib/ssh/doc/src/part_notes.xml
index f87efffe5c..700f76200c 100644
--- a/lib/ssh/doc/src/part_notes.xml
+++ b/lib/ssh/doc/src/part_notes.xml
@@ -31,8 +31,7 @@
<description>
<p>This document describes the changes made to the SSH application.
</p>
- <p>For information about older versions see
- <url href="part_notes_history_frame.html">release notes history</url>.</p> </description>
+ </description>
<xi:include file="notes.xml"/>
</part>
diff --git a/lib/ssh/doc/src/part_notes_history.xml b/lib/ssh/doc/src/part_notes_history.xml
deleted file mode 100644
index 49f72fd3db..0000000000
--- a/lib/ssh/doc/src/part_notes_history.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE part SYSTEM "part.dtd">
-
-<part>
- <header>
- <copyright>
- <year>2004</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
- </legalnotice>
-
- <title>Ssh</title>
- <prepared>Ingela Anderton Andin</prepared>
- <docno></docno>
- <date></date>
- <rev></rev>
- <file>part_notes.xml</file>
- </header>
- <include file="notes_history"></include>
-</part>
-
-
diff --git a/lib/ssh/vsn.mk b/lib/ssh/vsn.mk
index 016fb30c69..2b9df4ae60 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -1,9 +1,11 @@
#-*-makefile-*- ; force emacs to enter makefile-mode
-SSH_VSN = 1.1.7
+SSH_VSN = 1.1.8
APP_VSN = "ssh-$(SSH_VSN)"
-TICKETS = OTP-8121 \
+TICKETS = OTP-8356
+
+TICKETS_1.1.7 = OTP-8121 \
OTP-8277 \
OTP-8278 \
OTP-8201
diff --git a/lib/ssl/doc/src/create_certs.xml b/lib/ssl/doc/src/create_certs.xml
index 15958ee457..79cc8a0537 100644
--- a/lib/ssl/doc/src/create_certs.xml
+++ b/lib/ssl/doc/src/create_certs.xml
@@ -98,12 +98,12 @@
<title>Creating the Erlang root CA</title>
<p>The Erlang root CA is created with the command</p>
<code type="none">
-\011openssl req -new -x509 -config /some/path/req.cnf \\
-\011 -keyout /some/path/key.pem -out /some/path/cert.pem </code>
+ openssl req -new -x509 -config /some/path/req.cnf \\
+ -keyout /some/path/key.pem -out /some/path/cert.pem </code>
<p>where the option <c>-new</c> indicates that we want to create
a new certificate request and the option <c>-x509</c> implies
that a self-signed certificate is created.
- </p>
+ </p>
</section>
<section>
@@ -111,12 +111,12 @@
<p>The OTP CA is created by first creating a certificate request
with the command</p>
<code type="none">
-\011openssl req -new -config /some/path/req.cnf \\
-\011 -keyout /some/path/key.pem -out /some/path/req.pem </code>
+ openssl req -new -config /some/path/req.cnf \\
+ -keyout /some/path/key.pem -out /some/path/req.pem </code>
<p>and the ask the Erlang CA to sign it:</p>
<code type="none">
-\011openssl ca -batch -notext -config /some/path/req.cnf \\
-\011 -extensions ca_cert -in /some/path/req.pem -out /some/path/cert.pem </code>
+ openssl ca -batch -notext -config /some/path/req.cnf \\
+ -extensions ca_cert -in /some/path/req.pem -out /some/path/cert.pem </code>
<p>where the option <c>-extensions</c> refers to a section in the
configuration file saying that it should create a CA certificate,
and not a plain user certificate.
diff --git a/lib/ssl/doc/src/new_ssl.xml b/lib/ssl/doc/src/new_ssl.xml
index f50f714fe6..a11919eb51 100644
--- a/lib/ssl/doc/src/new_ssl.xml
+++ b/lib/ssl/doc/src/new_ssl.xml
@@ -437,30 +437,17 @@ end
</func>
<func>
- <name>peercert(Socket) -> </name>
- <name>peercert(Socket, Opts) -> {ok, Cert} | {error, Reason}</name>
+ <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name>
<fsummary>Return the peer certificate.</fsummary>
<type>
<v>Socket = sslsocket()</v>
- <v>Opts = [] | [otp] | [plain] </v>
- <v>Cert = term()</v>
+ <v>Cert = binary()</v>
<v>Subject = term()</v>
</type>
<desc>
- <p><c>peercert(Cert)</c> is equivalent to <c>peercert(Cert, [])</c>.
- </p>
- <p>The form of the returned certificate depends on the
- options.
- </p>
- <p>If the options list is empty the certificate is returned as
- a DER encoded binary.
- </p>
- <p>The option <c>otp</c> or <c>plain</c> implies that the
- certificate will be returned as a parsed ASN.1 structure in the
- form of an Erlang term. For detail see the public_key application.
- Currently only plain is officially supported see the public_key users
- guide.
- </p>
+ <p>The peer certificate is returned as a DER encoded binary.
+ The certificate can be decoded with <c>public_key:pkix_decode_cert/2</c>.
+ </p>
</desc>
</func>
<func>
diff --git a/lib/ssl/doc/src/pkix_certs.xml b/lib/ssl/doc/src/pkix_certs.xml
index 47818c1b7d..1de807cadc 100644
--- a/lib/ssl/doc/src/pkix_certs.xml
+++ b/lib/ssl/doc/src/pkix_certs.xml
@@ -34,219 +34,24 @@
<p>Certificates were originally defined by ITU (CCITT) and the latest
definitions are described in <cite id="X.509"></cite>, but those definitions
are (as always) not working.
- </p>
+ </p>
<p>Working certificate definitions for the Internet Community are found
- in the the PKIX RFCs <cite id="rfc3279"></cite>and <cite id="rfc3280"></cite>.
+ in the the PKIX RFCs <cite id="rfc3279"></cite> and <cite id="rfc3280"></cite>.
The parsing of certificates in the Erlang/OTP SSL application is
based on those RFCS.
- </p>
+ </p>
<p>Certificates are defined in terms of ASN.1 (<cite id="X.680"></cite>).
For an introduction to ASN.1 see <url href="http://asn1.elibel.tm.fr/">ASN.1 Information Site</url>.
- </p>
+ </p>
</section>
<section>
<title>PKIX Certificates</title>
- <p>Here we base the PKIX certificate definitions in RFCs <cite id="rfc3279"></cite>and <cite id="rfc3280"></cite>. We however present the
- definitions according to <c>SSL-PKIX.asn1</c> module,
- which is an amelioration of the <c>PKIX1Explicit88.asn1</c>,
- <c>PKIX1Implicit88.asn1</c>, and <c>PKIX1Algorithms88.asn1</c>
- modules. You find all these modules in the <c>pkix</c> subdirectory
- of SSL.
- </p>
- <p>The Erlang terms that are returned by the functions
- <c>ssl:peercert/1/2</c>, <c>ssl_pkix:decode_cert/1/2</c>, and
- <c>ssl_pkix:decode_cert_file/1/2</c> when the option <c>ssl</c>
- is used in those functions, correspond the ASN.1 structures
- described in the sequel.
- </p>
-
- <section>
- <title>Certificate and TBSCertificate</title>
- <code type="none">
-Certificate ::= SEQUENCE {
- tbsCertificate TBSCertificate,
- signatureAlgorithm SignatureAlgorithm,
- signature BIT STRING }
-
-TBSCertificate ::= SEQUENCE {
- version [0] Version DEFAULT v1,
- serialNumber CertificateSerialNumber,
- signature SignatureAlgorithm,
- issuer Name,
- validity Validity,
- subject Name,
- subjectPublicKeyInfo SubjectPublicKeyInfo,
- issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
- -- If present, version MUST be v2 or v3
- subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
- -- If present, version MUST be v2 or v3
- extensions [3] Extensions OPTIONAL
- -- If present, version MUST be v3 -- }
-
-Version ::= INTEGER { v1(0), v2(1), v3(2) }
-
-CertificateSerialNumber ::= INTEGER
-
-Validity ::= SEQUENCE {
- notBefore Time,
- notAfter Time }
-
-Time ::= CHOICE {
- utcTime UTCTime,
- generalTime GeneralizedTime }
- </code>
- <p>The meaning of the fields <c>version</c>, <c>serialNumber</c>,
- and <c>validity</c> are quite obvious given the type definitions
- above, so we do not go further into their details.
- </p>
- <p>The <c>signatureAlgorithm</c> field of <c>Certificate</c> and
- the <c>signature</c> field of <c>TBSCertificate</c> contain
- the name and parameters of the algorithm used for signing the
- certificate. The values of these two fields must be equal.
- </p>
- <p>The <c>signature</c> field of <c>Certificate</c> contains the
- value of the signature that the issuer computed by using the
- prescribed algorithm.
- </p>
- <p>The <c><![CDATA[issuer<c> and <c>subject]]></c> fields can contain many
- different types av data, and is therefore considered in a
- separate section. The same holds for the <c>extensions</c>
- field.
- The <c>issuerUniqueID</c> and the <c>subjectUniqueID</c> fields
- are not considered further.</p>
- </section>
-
- <section>
- <title>TBSCertificate issuer and subject</title>
- <p></p>
- <code type="none"><![CDATA[
-Name ::= CHOICE { -- only one possibility for now --
- rdnSequence RDNSequence }
-
-RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
-
-DistinguishedName ::= RDNSequence
-
-RelativeDistinguishedName ::=
- SET SIZE (1 .. MAX) OF AttributeTypeAndValue
-
-AttributeTypeAndValue ::= SEQUENCE {
- type ATTRIBUTE-TYPE-AND-VALUE-CLASS.&id
-\011\011({SupportedAttributeTypeAndValues}),
- value ATTRIBUTE-TYPE-AND-VALUE-CLASS.&Type
-\011\011({SupportedAttributeTypeAndValues}{@type}) }
-
-SupportedAttributeTypeAndValues ATTRIBUTE-TYPE-AND-VALUE-CLASS ::=
-\011{ name | surname | givenName | initials | generationQualifier |
-\011 commonName | localityName | stateOrProvinceName | organizationName |
-\011 organizationalUnitName | title | dnQualifier | countryName |
-\011 serialNumber | pseudonym | domainComponent | emailAddress } ]]></code>
- </section>
-
- <section>
- <title>TBSCertificate extensions</title>
- <p>The <c>extensions</c> field of a <c>TBScertificate</c> is a
- sequence of type <c>Extension</c>, defined as follows,</p>
- <code type="none">
-Extension ::= SEQUENCE {
- extnID OBJECT IDENTIFIER,
- critical BOOLEAN DEFAULT FALSE,
- extnValue ANY } </code>
- <p>Each extension has a unique object identifier. An extension
- with a <c>critical</c> value set to <c>TRUE</c><em>must</em>
- be recognised by the reader of a certificate, or else the
- certificate must be rejected.
- </p>
- <p>Extensions are divided into two groups: standard extensions
- and internet certificate extensions. All extensions listed in
- the table that follows are standard extensions, except for
- <c>authorityInfoAccess</c> and <c>subjectInfoAccess</c>, which
- are internet extensions.
- </p>
- <p>Depending on the object identifier the <c>extnValue</c> is
- parsed into an appropriate welldefined structure.
- </p>
- <p>The following table shows the purpose of each extension, but
- does not specify the structure. To see the structure consult
- the <c>PKIX1Implicit88.asn1</c> module.
- </p>
- <table>
- <row>
- <cell align="left" valign="middle">authorityKeyIdentifier</cell>
- <cell align="left" valign="middle">Used by to identify a certificate signed that has multiple signing keys. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">subjectKeyIdentifier</cell>
- <cell align="left" valign="middle">Used to identify certificates that contain a public key. Must appear i CA certificates.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">keyUsage </cell>
- <cell align="left" valign="middle">Defines the purpose of the certificate. Can be one or several of<c>digitalSignature</c>, <c>nonRepudiation</c>,<c>keyEncipherment</c>, <c>dataEncipherment</c>,<c>keyAgreement</c>, <c>keyCertSign</c>, <c>cRLSign</c>,<c>encipherOnly</c>, <c>decipherOnly</c>.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">privateKeyUsagePeriod </cell>
- <cell align="left" valign="middle">Allows certificate issuer to provide a private key usage period to be short than the certificate usage period.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">certificatePolicies</cell>
- <cell align="left" valign="middle">Contains one or more policy information terms indicating the policies under which the certificate has been issued.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">policyMappings</cell>
- <cell align="left" valign="middle">Used i CA certificates. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">subjectAltName</cell>
- <cell align="left" valign="middle">Allows additional identities to be bound the the subject. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">issuerAltName</cell>
- <cell align="left" valign="middle">Allows additional identities to be bound the the issuer.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">subjectDirectoryAttributes</cell>
- <cell align="left" valign="middle">Conveys identity attributes of the subject.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">basicConstraints</cell>
- <cell align="left" valign="middle">Tells if the certificate holder is a CA or not.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">nameConstraints</cell>
- <cell align="left" valign="middle">Used in CA certificates.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">policyConstraints</cell>
- <cell align="left" valign="middle">Used in CA certificates.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">extKeyUsage</cell>
- <cell align="left" valign="middle">Indicates for which purposed the public key may be used. </cell>
- </row>
- <row>
- <cell align="left" valign="middle">cRLDistributionPoints</cell>
- <cell align="left" valign="middle">Indicates how CRL (Certificate Revokation List) information is obtained.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">inhibitAnyPolicy</cell>
- <cell align="left" valign="middle">Used i CA certificates.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">freshestCRL</cell>
- <cell align="left" valign="middle">For CRLs.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">authorityInfoAccess</cell>
- <cell align="left" valign="middle">How to access CA information of the issuer of the certificate.</cell>
- </row>
- <row>
- <cell align="left" valign="middle">subjectInfoAccess</cell>
- <cell align="left" valign="middle">How to access CA information of the subject of the certificate.</cell>
- </row>
- <tcaption>PKIX Extensions</tcaption>
- </table>
- </section>
+ <p>Certificate handling is now handled by the <c>public_key</c> application.</p>
+ <p>
+ DER encoded certificates returned by <c>ssl:peercert/1</c> can for example
+ be decoded by the <c>public_key:pkix_decode_cert/2</c> function.
+ </p>
</section>
</chapter>
diff --git a/lib/ssl/doc/src/remember.xml b/lib/ssl/doc/src/remember.xml
deleted file mode 100644
index 799627a33c..0000000000
--- a/lib/ssl/doc/src/remember.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="latin1" ?>
-<!DOCTYPE chapter SYSTEM "chapter.dtd">
-
-<chapter>
- <header>
- <copyright>
- <year>2003</year><year>2009</year>
- <holder>Ericsson AB. All Rights Reserved.</holder>
- </copyright>
- <legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- </legalnotice>
-
- <title>PKIX Certificates</title>
- <prepared>UAB/F/P Peter H&ouml;gfeldt</prepared>
- <docno></docno>
- <date>2003-06-09</date>
- <rev>A</rev>
- <file>pkix_certs.sgml</file>
- </header>
-
- <section>
- <title>Introduction to Certificates</title>
- <p><em>Outline:</em></p>
- <list type="bulleted">
- <item>SSL/TLS protocol - server must have certificate - -what
- the the server sends to the client - client may verify the
- server - server may ask client for certificate - what the
- client sends to the server - server may then verify the client
- - verification - certificate chains - root certificates -
- public keys - key agreement - purpose of certificate - main
- contents of certificate - contents have increased as time went
- by - common file formats for certificates.
- </item>
- <item>private keys - password protection - key generation - file
- formats.
- </item>
- <item>ssl_pkix and alternate decodings.
- </item>
- <item>Attribute Certificates (not used by SSL).
- </item>
- <item>Certificate requests - certificate authorities - signing of
- certificates - certificate revocation lists.
- </item>
- <item>standards: ASN.1, X.509, X.520, PKIX, PKCS, PEM.
- </item>
- <item>incompatibilities between standards (X.509-1997 vs old) - the
- ASN.1 problem of ANY, BIT STRING and OCTET STRING - the module
- ssl_pkix.
- </item>
- <item>test suites: NIST
- </item>
- <item>Warnings: *creation* of trusted certificate (OpenSSL).
- </item>
- <item>Erlang SSL and certificates
- </item>
- <item>The need for seeding the random generator. See also John
- S. Denker: High-Entropy Symbol Generator
- (http://www.monmouth.com/~jsd).
- </item>
- <item>links to standards and documents. Books (Rescorla).
- </item>
- <item>ASN.1 crash course.
- </item>
- <item>Nagel algorithm.
- </item>
- </list>
- <p>For an introduction to ASN.1 see <url href="http://asn1.elibel.tm.fr/">ASN.1 Information Site</url>.
- </p>
- </section>
-</chapter>
-
-
diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml
index 9b780b14ce..217eb791d0 100644
--- a/lib/ssl/doc/src/ssl.xml
+++ b/lib/ssl/doc/src/ssl.xml
@@ -347,39 +347,17 @@
</desc>
</func>
<func>
- <name>peercert(Socket) -> </name>
- <name>peercert(Socket, Opts) -> {ok, Cert} | {ok, Subject} | {error, Reason}</name>
+ <name>peercert(Socket) -> {ok, Cert} | {error, Reason}</name>
<fsummary>Return the peer certificate.</fsummary>
<type>
<v>Socket = sslsocket()</v>
- <v>Opts = [pkix | ssl | subject]()</v>
- <v>Cert = term()()</v>
+ <v>Cert = binary()()</v>
<v>Subject = term()()</v>
</type>
<desc>
- <p><c>peercert(Cert)</c> is equivalent to <c>peercert(Cert, [])</c>.
- </p>
- <p>The form of the returned certificate depends on the
- options.
- </p>
- <p>If the options list is empty the certificate is returned as
- a DER encoded binary.
- </p>
- <p>The options <c>pkix</c> and <c>ssl</c> implies that the
- certificate is returned as a parsed ASN.1 structure in the
- form of an Erlang term.
- </p>
- <p>The <c>ssl</c> option gives a more elaborate return
- structure, with more explicit information. In particular
- object identifiers are replaced by atoms.
- </p>
- <p>The options <c>pkix</c>, and <c>ssl</c> are mutually
- exclusive.
- </p>
- <p>The option <c>subject</c> implies that only the subject's
- distinguished name part of the peer certificate is returned.
- It can only be used together with the option <c>pkix</c> or
- the option <c>ssl</c>.</p>
+ <p>Returns the DER encoded peer certificate, the certificate can be decoded with
+ <c>public_key:pkix_decode_cert/2</c>.
+ </p>
</desc>
</func>
<func>
@@ -719,8 +697,7 @@
<section>
<title>SEE ALSO</title>
- <p>gen_tcp(3), inet(3)
- </p>
+ <p>gen_tcp(3), inet(3) public_key(3) </p>
</section>
</erlref>
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index f5d8b9bb48..739cd0bffd 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.xml
@@ -729,6 +729,36 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
updated internal data.</p>
</desc>
</func>
+ <func>
+ <name>Module:format_status(normal, [PDict, StateData]) -> Status</name>
+ <fsummary>Optional function for providing a term describing the
+ current gen_fsm status.</fsummary>
+ <type>
+ <v>PDict = [{Key, Value}]</v>
+ <v>StateData = term()</v>
+ <v>Status = [term()]</v>
+ </type>
+ <desc>
+ <p><em>This callback is optional, so callback modules need not
+ export it. The gen_fsm module provides a default
+ implementation of this function that returns the callback
+ module state data.</em></p>
+ <p>This function is called by a gen_fsm process when one
+ of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
+ is invoked to get the gen_fsm status. A callback module
+ wishing to customise the <c>sys:get_status/1,2</c> return
+ value exports an instance of <c>format_status/2</c> that
+ returns a term describing the current status of the
+ gen_fsm.</p>
+ <p><c>PDict</c> is the current value of the gen_fsm's
+ process dictionary.</p>
+ <p><c>StateData</c> is the internal state data of the
+ gen_fsm.</p>
+ <p>The function should return <c>Status</c>, a list of one or
+ more terms that customise the details of the current state
+ and status of the gen_fsm.</p>
+ </desc>
+ </func>
</funcs>
<section>
diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml
index 8496802259..30c04d1d52 100644
--- a/lib/stdlib/doc/src/gen_server.xml
+++ b/lib/stdlib/doc/src/gen_server.xml
@@ -598,6 +598,35 @@ gen_server:abcast -----> Module:handle_cast/2
<p>The function should return the updated internal state.</p>
</desc>
</func>
+ <func>
+ <name>Module:format_status(normal, [PDict, State]) -> Status</name>
+ <fsummary>Optional function for providing a term describing the
+ current gen_server status.</fsummary>
+ <type>
+ <v>PDict = [{Key, Value}]</v>
+ <v>State = term()</v>
+ <v>Status = [term()]</v>
+ </type>
+ <desc>
+ <p><em>This callback is optional, so callback modules need not
+ export it. The gen_server module provides a default
+ implementation of this function that returns the callback
+ module state.</em></p>
+ <p>This function is called by a gen_server process when one
+ of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
+ is invoked to get the gen_server status. A callback module
+ wishing to customise the <c>sys:get_status/1,2</c> return
+ value exports an instance of <c>format_status/2</c> that
+ returns a term describing the current status of the
+ gen_server.</p>
+ <p><c>PDict</c> is the current value of the gen_server's
+ process dictionary.</p>
+ <p><c>State</c> is the internal state of the gen_server.</p>
+ <p>The function should return <c>Status</c>, a list of one or
+ more terms that customise the details of the current state
+ and status of the gen_server.</p>
+ </desc>
+ </func>
</funcs>
<section>
diff --git a/lib/stdlib/doc/src/sys.xml b/lib/stdlib/doc/src/sys.xml
index a395a8a415..10ead62073 100644
--- a/lib/stdlib/doc/src/sys.xml
+++ b/lib/stdlib/doc/src/sys.xml
@@ -4,23 +4,21 @@
<erlref>
<header>
<copyright>
- <year>1996</year>
- <year>2007</year>
- <holder>Ericsson AB, All Rights Reserved</holder>
+ <year>1996</year><year>2009</year>
+ <holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
- The contents of this file are subject to the Erlang Public License,
- Version 1.1, (the "License"); you may not use this file except in
- compliance with the License. You should have received a copy of the
- Erlang Public License along with this software. If not, it can be
- retrieved online at http://www.erlang.org/.
-
- Software distributed under the License is distributed on an "AS IS"
- basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- the License for the specific language governing rights and limitations
- under the License.
-
- The Initial Developer of the Original Code is Ericsson AB.
+ The contents of this file are subject to the Erlang Public License,
+ Version 1.1, (the "License"); you may not use this file except in
+ compliance with the License. You should have received a copy of the
+ Erlang Public License along with this software. If not, it can be
+ retrieved online at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ the License for the specific language governing rights and limitations
+ under the License.
+
</legalnotice>
<title>sys</title>
@@ -237,6 +235,17 @@
</type>
<desc>
<p>Gets the status of the process.</p>
+ <p>The value of <c>Misc</c> varies for different types of
+ processes. For example, a <c>gen_server</c> process returns
+ the callback module's state, and a <c>gen_fsm</c> process
+ returns information such as its current state name. Callback
+ modules for <c>gen_server</c> and <c>gen_fsm</c> can also
+ customise the value of <c>Misc</c> by exporting
+ a <c>format_status/2</c> function that contributes
+ module-specific information;
+ see <seealso marker="gen_server#format_status/2">gen_server:format_status/2</seealso>
+ and <seealso marker="gen_fsm#format_status/2">gen_fsm:format_status/2</seealso>
+ for more details.</p>
</desc>
</func>
<func>
diff --git a/lib/stdlib/src/c.erl b/lib/stdlib/src/c.erl
index 9e4cec5db2..433833e233 100644
--- a/lib/stdlib/src/c.erl
+++ b/lib/stdlib/src/c.erl
@@ -197,7 +197,9 @@ nc(File, Opts0) when is_list(Opts0) ->
Opts = Opts0 ++ [report_errors, report_warnings],
case compile:file(File, Opts) of
{ok,Mod} ->
- Fname = concat([File, code:objfile_extension()]),
+ Dir = outdir(Opts),
+ Obj = filename:basename(File, ".erl") ++ code:objfile_extension(),
+ Fname = filename:join(Dir, Obj),
case file:read_file(Fname) of
{ok,Bin} ->
rpc:eval_everywhere(code,load_binary,[Mod,Fname,Bin]),
diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl
index f3775f967a..ba0275ae2b 100644
--- a/lib/stdlib/src/gen_fsm.erl
+++ b/lib/stdlib/src/gen_fsm.erl
@@ -603,7 +603,12 @@ get_msg(Msg) -> Msg.
format_status(Opt, StatusData) ->
[PDict, SysState, Parent, Debug, [Name, StateName, StateData, Mod, _Time]] =
StatusData,
- Header = lists:concat(["Status for state machine ", Name]),
+ NameTag = if is_pid(Name) ->
+ pid_to_list(Name);
+ is_atom(Name) ->
+ Name
+ end,
+ Header = lists:concat(["Status for state machine ", NameTag]),
Log = sys:get_debug(log, Debug, []),
Specfic =
case erlang:function_exported(Mod, format_status, 2) of
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index 3df6f4bb90..7ea7de8d58 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -334,6 +334,10 @@ obsolete_1(ssl_pkix, decode_cert_file, A) when A =:= 1; A =:= 2 ->
{deprecated,"deprecated (will be removed in R14B); use public_key:pem_to_der/1 and public_key:pkix_decode_cert/2 instead"};
obsolete_1(ssl_pkix, decode_cert, A) when A =:= 1; A =:= 2 ->
{deprecated,{public_key,pkix_decode_cert,2},"R14B"};
+
+%% Added in R13B04.
+obsolete_1(erlang, concat_binary, 1) ->
+ {deprecated,{erlang,list_to_binary,1},"R14B"};
obsolete_1(_, _, _) ->
no.
diff --git a/lib/stdlib/src/sys.erl b/lib/stdlib/src/sys.erl
index e0f2dbcd3c..12209c16d7 100644
--- a/lib/stdlib/src/sys.erl
+++ b/lib/stdlib/src/sys.erl
@@ -245,8 +245,17 @@ do_cmd(SysState, Other, _Parent, _Mod, Debug, Misc) ->
{SysState, {error, {unknown_system_msg, Other}}, Debug, Misc}.
get_status(SysState, Parent, Mod, Debug, Misc) ->
+ PDict = get(),
+ FmtMisc =
+ case erlang:function_exported(Mod, format_status, 2) of
+ true ->
+ FmtArgs = [PDict, SysState, Parent, Debug, Misc],
+ Mod:format_status(normal, FmtArgs);
+ _ ->
+ Misc
+ end,
{status, self(), {module, Mod},
- [get(), SysState, Parent, Debug, Misc]}.
+ [PDict, SysState, Parent, Debug, FmtMisc]}.
%%-----------------------------------------------------------------
%% These are the system debug commands.
diff --git a/lib/stdlib/test/c_SUITE.erl b/lib/stdlib/test/c_SUITE.erl
index 5608d73d19..2edbc7ab4c 100644
--- a/lib/stdlib/test/c_SUITE.erl
+++ b/lib/stdlib/test/c_SUITE.erl
@@ -18,15 +18,16 @@
%%
-module(c_SUITE).
-export([all/1]).
--export([c_1/1, c_2/1, c_3/1, c_4/1, memory/1]).
+-export([c_1/1, c_2/1, c_3/1, c_4/1, nc_1/1, nc_2/1, nc_3/1, nc_4/1,
+ memory/1]).
-include("test_server.hrl").
--import(c, [c/2]).
+-import(c, [c/2, nc/2]).
all(doc) -> ["Test cases for the 'c' module."];
all(suite) ->
- [c_1, c_2, c_3, c_4, memory].
+ [c_1, c_2, c_3, c_4, nc_1, nc_2, nc_3, nc_4, memory].
%%% Write output to a directory other than current directory:
@@ -34,7 +35,7 @@ c_1(doc) ->
["Checks that c:c works also with option 'outdir' [ticket OTP-1209]."];
c_1(suite) ->
[];
-c_1(Config) when list(Config) ->
+c_1(Config) when is_list(Config) ->
?line R = filename:join(?config(data_dir, Config), "m.erl"),
?line W = ?config(priv_dir, Config),
?line Result = c(R,[{outdir,W}]),
@@ -44,7 +45,7 @@ c_2(doc) ->
["Checks that c:c works also with option 'outdir' [ticket OTP-1209]."];
c_2(suite) ->
[];
-c_2(Config) when list(Config) ->
+c_2(Config) when is_list(Config) ->
?line R = filename:join(?config(data_dir, Config), "m"),
?line W = ?config(priv_dir, Config),
?line Result = c(R,[{outdir,W}]),
@@ -59,7 +60,7 @@ c_3(doc) ->
"directory). [ticket OTP-1209]."];
c_3(suite) ->
[];
-c_3(Config) when list(Config) ->
+c_3(Config) when is_list(Config) ->
?line R = filename:join(?config(data_dir, Config), "m.erl"),
?line W = ?config(priv_dir, Config),
?line file:set_cwd(W),
@@ -71,18 +72,68 @@ c_4(doc) ->
"directory). [ticket OTP-1209]."];
c_4(suite) ->
[];
-c_4(Config) when list(Config) ->
+c_4(Config) when is_list(Config) ->
?line R = filename:join(?config(data_dir, Config), "m"),
?line W = ?config(priv_dir, Config),
?line file:set_cwd(W),
?line Result = c(R,[{outdir,W}]),
?line {ok, m} = Result.
+%%% Write output to a directory other than current directory:
+
+nc_1(doc) ->
+ ["Checks that c:nc works also with option 'outdir'."];
+nc_1(suite) ->
+ [];
+nc_1(Config) when is_list(Config) ->
+ ?line R = filename:join(?config(data_dir, Config), "m.erl"),
+ ?line W = ?config(priv_dir, Config),
+ ?line Result = nc(R,[{outdir,W}]),
+ ?line {ok, m} = Result.
+
+nc_2(doc) ->
+ ["Checks that c:nc works also with option 'outdir'."];
+nc_2(suite) ->
+ [];
+nc_2(Config) when is_list(Config) ->
+ ?line R = filename:join(?config(data_dir, Config), "m"),
+ ?line W = ?config(priv_dir, Config),
+ ?line Result = nc(R,[{outdir,W}]),
+ ?line {ok, m} = Result.
+
+
+%%% Put results in current directory (or rather, change current dir
+%%% to the output dir):
+
+nc_3(doc) ->
+ ["Checks that c:nc works also with option 'outdir' (same as current"
+ "directory)."];
+nc_3(suite) ->
+ [];
+nc_3(Config) when is_list(Config) ->
+ ?line R = filename:join(?config(data_dir, Config), "m.erl"),
+ ?line W = ?config(priv_dir, Config),
+ ?line file:set_cwd(W),
+ ?line Result = nc(R,[{outdir,W}]),
+ ?line {ok, m} = Result.
+
+nc_4(doc) ->
+ ["Checks that c:nc works also with option 'outdir' (same as current"
+ "directory)."];
+nc_4(suite) ->
+ [];
+nc_4(Config) when is_list(Config) ->
+ ?line R = filename:join(?config(data_dir, Config), "m"),
+ ?line W = ?config(priv_dir, Config),
+ ?line file:set_cwd(W),
+ ?line Result = nc(R,[{outdir,W}]),
+ ?line {ok, m} = Result.
+
memory(doc) ->
["Checks that c:memory/[0,1] returns consistent results."];
memory(suite) ->
[];
-memory(Config) when list(Config) ->
+memory(Config) when is_list(Config) ->
try
?line ML = c:memory(),
?line T = mget(total, ML),
@@ -112,5 +163,5 @@ mget(K, L) ->
?line test_v(V).
% Help function for c_SUITE:memory/1
-test_v(V) when integer(V) ->
+test_v(V) when is_integer(V) ->
?line V.
diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl
index 62f8b2f9dd..23c1d9a193 100644
--- a/lib/stdlib/test/gen_fsm_SUITE.erl
+++ b/lib/stdlib/test/gen_fsm_SUITE.erl
@@ -30,7 +30,7 @@
-export([shutdown/1]).
--export([sys/1, sys1/1]).
+-export([sys/1, sys1/1, call_format_status/1]).
-export([hibernate/1,hiber_idle/3,hiber_wakeup/3,hiber_idle/2,hiber_wakeup/2]).
@@ -42,7 +42,7 @@
% The gen_fsm behaviour
-export([init/1, handle_event/3, handle_sync_event/4, terminate/3,
- handle_info/3]).
+ handle_info/3, format_status/2]).
-export([idle/2, idle/3,
timeout/2,
wfor_conf/2, wfor_conf/3,
@@ -305,7 +305,7 @@ shutdown(Config) when is_list(Config) ->
ok.
-sys(suite) -> [sys1].
+sys(suite) -> [sys1, call_format_status].
sys1(Config) when is_list(Config) ->
?line {ok, Pid} =
@@ -317,6 +317,13 @@ sys1(Config) when is_list(Config) ->
?line sys:resume(Pid),
?line stop_it(Pid).
+call_format_status(Config) when is_list(Config) ->
+ ?line {ok, Pid} = gen_fsm:start(gen_fsm_SUITE, [], []),
+ ?line Status = sys:get_status(Pid),
+ ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data]} = Status,
+ ?line [format_status_called | _] = lists:reverse(Data),
+ ?line stop_it(Pid).
+
%% Hibernation
hibernate(suite) -> [];
@@ -836,3 +843,6 @@ handle_sync_event(stop_shutdown_reason, _From, _State, Data) ->
{stop, {shutdown,reason}, {shutdown,reason}, Data};
handle_sync_event({get, _Pid}, _From, State, Data) ->
{reply, {state, State, Data}, State, Data}.
+
+format_status(_Opt, [_Pdict, _StateData]) ->
+ [format_status_called].
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index 86a5a65ba3..6efdce78a1 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_SUITE.erl
@@ -30,7 +30,7 @@
call_remote_n1/1, call_remote_n2/1, call_remote_n3/1, spec_init/1,
spec_init_local_registered_parent/1,
spec_init_global_registered_parent/1,
- otp_5854/1, hibernate/1, otp_7669/1
+ otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1
]).
% spawn export
@@ -42,7 +42,7 @@
% The gen_server behaviour
-export([init/1, handle_call/3, handle_cast/2,
- handle_info/2, terminate/2]).
+ handle_info/2, terminate/2, format_status/2]).
all(suite) ->
[start, crash, call, cast, cast_fast, info,
@@ -51,7 +51,7 @@ all(suite) ->
call_remote_n2, call_remote_n3, spec_init,
spec_init_local_registered_parent,
spec_init_global_registered_parent,
- otp_5854,hibernate,otp_7669].
+ otp_5854, hibernate, otp_7669, call_format_status].
-define(default_timeout, ?t:minutes(1)).
@@ -851,7 +851,7 @@ otp_5854(Config) when is_list(Config) ->
ok.
%% If initialization fails (with ignore or {stop,Reason}),
-%% make sure that the process is not registered when gen_sever:start()
+%% make sure that the process is not registered when gen_server:start()
%% returns.
otp_7669(Config) when is_list(Config) ->
@@ -887,6 +887,24 @@ do_otp_7669_stop() ->
?MODULE, stop, []),
?line undefined = global:whereis_name(?MODULE).
+%% Verify that sys:get_status correctly calls our format_status/2 fun
+%%
+call_format_status(suite) ->
+ [];
+call_format_status(doc) ->
+ ["Test that sys:get_status/1,2 calls format_status/2"];
+call_format_status(Config) when is_list(Config) ->
+ ?line {ok, Pid} = gen_server:start_link({local, call_format_status},
+ gen_server_SUITE, [], []),
+ ?line Status1 = sys:get_status(call_format_status),
+ ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data1]} = Status1,
+ ?line [format_status_called | _] = lists:reverse(Data1),
+ ?line Status2 = sys:get_status(call_format_status, 5000),
+ ?line {status, Pid, _Mod, [_PDict, running, _Parent, _, Data2]} = Status2,
+ ?line [format_status_called | _] = lists:reverse(Data2),
+ ok.
+
+
%%--------------------------------------------------------------
%% Help functions to spec_init_*
start_link(Init, Options) ->
@@ -1046,4 +1064,5 @@ terminate({From, stopped_info}, _State) ->
terminate(_Reason, _State) ->
ok.
-
+format_status(_Opt, [_PDict, _State]) ->
+ [format_status_called].
diff --git a/lib/tools/doc/src/notes.xml b/lib/tools/doc/src/notes.xml
index 59f600145e..e6c074cc7d 100644
--- a/lib/tools/doc/src/notes.xml
+++ b/lib/tools/doc/src/notes.xml
@@ -30,6 +30,21 @@
</header>
<p>This document describes the changes made to the Tools application.</p>
+<section><title>Tools 2.6.5.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>A bug concerning bit comprehensions has been fixed
+ in Cover. The bug was introduced in R13B03.
+ (Thanks to Matthew Sackman.)</p>
+ <p>Own Id: OTP-8340</p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Tools 2.6.5</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index f623e3a1ee..4fc4826238 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -72,7 +72,7 @@
;; Variables:
-(defconst erlang-version "2.6.1"
+(defconst erlang-version "2.6.2"
"The version number of Erlang mode.")
(defvar erlang-root-dir nil
@@ -3792,9 +3792,9 @@ Value is list (stack token-start token-type in-what)."
;; Clause end
((= (following-char) ?\;)
- (if (and stack (and (eq (car (car stack)) 'when)
- (eq (car (car (cdr (cdr stack)))) 'spec)))
- (erlang-pop stack))
+ (if (eq (car (car (last stack))) 'spec)
+ (while (memq (car (car stack)) '(when ::))
+ (erlang-pop stack)))
(if (and stack (eq (car (car stack)) '->))
(erlang-pop stack))
(forward-char 1))
@@ -3955,15 +3955,16 @@ Return nil if inside string, t if in a comment."
(nth 2 stack-top))))
(t
(goto-char (nth 1 stack-top))
- (cond ((looking-at "[({]\\s *\\($\\|%\\)")
- ;; Line ends with parenthesis.
- (erlang-indent-parenthesis (nth 2 stack-top)))
- (t
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (1+ (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column))))))
+ (let ((base (cond ((looking-at "[({]\\s *\\($\\|%\\)")
+ ;; Line ends with parenthesis.
+ (erlang-indent-parenthesis (nth 2 stack-top)))
+ (t
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (1+ (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column)))))
+ (erlang-indent-standard indent-point token base 't)))))
;;
((eq (car stack-top) '<<)
;; Element of binary (possible comprehension) expression,
@@ -4047,33 +4048,8 @@ Return nil if inside string, t if in a comment."
0))
base)) ;; old catch
(t
- ;; Look at last thing to see how we are to move relative
- ;; to the base.
- (goto-char token)
- (cond ((looking-at "||\\|,\\|->")
- base)
- ((erlang-at-keyword)
- (+ (current-column) erlang-indent-level))
- ((or (= (char-syntax (following-char)) ?.)
- (erlang-at-operator))
- (+ base erlang-indent-level))
- (t
- (goto-char indent-point)
- (cond ((memq (following-char) '(?\( ?{))
- ;; Function application or record.
- (+ (erlang-indent-find-preceding-expr)
- erlang-argument-indent))
- ;; Empty line, or end; treat it as the end of
- ;; the block. (Here we have a choice: should
- ;; the user be forced to reindent continued
- ;; lines, or should the "end" be reindented?)
-
- ;; Avoid treating comments a continued line.
- ((= (following-char) ?%)
- base)
- ;; Continued line (e.g. line beginning
- ;; with an operator.)
- (t (+ base erlang-indent-level)))))))))
+ (erlang-indent-standard indent-point token base 'nil)
+ ))))
))
((eq (car stack-top) 'when)
(goto-char (nth 1 stack-top))
@@ -4105,21 +4081,55 @@ Return nil if inside string, t if in a comment."
(+ 2 (nth 2 stack-top)))
((looking-at "::[^_a-zA-Z0-9]")
(nth 2 stack-top))
- (t
- (goto-char (nth 1 stack-top))
- (cond ((looking-at "::\\s *\\($\\|%\\)")
- ;; Line ends with ::
- (+ (erlang-indent-find-preceding-expr 2)
- erlang-argument-indent))
- ;; (* 2 erlang-indent-level))
- (t
- ;; Indent to the same column as the first
- ;; argument.
- (goto-char (+ 2 (nth 1 stack-top)))
- (skip-chars-forward " \t")
- (current-column))))))
+ (t
+ (let ((start-alternativ (if (looking-at "|") 2 0)))
+ (goto-char (nth 1 stack-top))
+ (- (cond ((looking-at "::\\s *\\($\\|%\\)")
+ ;; Line ends with ::
+ (if (eq (car (car (last stack))) 'spec)
+ (+ (erlang-indent-find-preceding-expr 1)
+ erlang-argument-indent)
+ (+ (erlang-indent-find-preceding-expr 2)
+ erlang-argument-indent)))
+ (t
+ ;; Indent to the same column as the first
+ ;; argument.
+ (goto-char (+ 2 (nth 1 stack-top)))
+ (skip-chars-forward " \t")
+ (current-column))) start-alternativ)))))
)))
+(defun erlang-indent-standard (indent-point token base inside-parenthesis)
+ "Standard indent when in blocks or tuple or arguments.
+ Look at last thing to see in what state we are, move relative to the base."
+ (goto-char token)
+ (cond ((looking-at "||\\|,\\|->\\||")
+ base)
+ ((erlang-at-keyword)
+ (+ (current-column) erlang-indent-level))
+ ((or (= (char-syntax (following-char)) ?.)
+ (erlang-at-operator))
+ (+ base erlang-indent-level))
+ (t
+ (goto-char indent-point)
+ (cond ((memq (following-char) '(?\( ?{))
+ ;; Function application or record.
+ (+ (erlang-indent-find-preceding-expr)
+ erlang-argument-indent))
+ ;; Empty line, or end; treat it as the end of
+ ;; the block. (Here we have a choice: should
+ ;; the user be forced to reindent continued
+ ;; lines, or should the "end" be reindented?)
+
+ ;; Avoid treating comments a continued line.
+ ((= (following-char) ?%)
+ base)
+ ;; Continued line (e.g. line beginning
+ ;; with an operator.)
+ (t
+ (if (or (erlang-at-operator) (not inside-parenthesis))
+ (+ base erlang-indent-level)
+ base))))))
(defun erlang-indent-find-base (stack indent-point &optional offset skip)
"Find the base column for current stack."
@@ -4946,6 +4956,7 @@ non-whitespace characters following the point on the current line."
(setq erlang-electric-newline-inhibit nil)
(setq erlang-electric-newline-inhibit t)
(undo-boundary)
+ (erlang-indent-line)
(end-of-line)
(newline)
(condition-case nil
diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented
index b2cc23b92b..1ccced9177 100644
--- a/lib/tools/emacs/test.erl.indented
+++ b/lib/tools/emacs/test.erl.indented
@@ -44,6 +44,24 @@
b
}).
+-record(record3, {a = 8#42423 bor
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+ 234,
+ d}).
+
+-record(record4, {
+ a = 8#42423 bor
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+ 234,
+ d}).
+
+
-define(MACRO_1, macro).
-define(MACRO_2(_), macro).
@@ -51,8 +69,10 @@
-type ann() :: Var :: integer().
-type ann2() :: Var ::
- 'return' | 'return_white_spaces' | 'return_comments'
- | 'text' | ann().
+ 'return'
+ | 'return_white_spaces'
+ | 'return_comments'
+ | 'text' | ann().
-type paren() ::
(ann2()).
-type t1() :: atom().
@@ -89,7 +109,7 @@
fun((nonempty_maybe_improper_list('integer', any())|
1|2|3|a|b|<<_:3,_:_*14>>|integer()) ->
nonempty_maybe_improper_list('integer', any())|
- 1|2|3|a|b|<<_:3,_:_*14>>|integer()).
+ 1|2|3|a|b|<<_:3,_:_*14>>|integer()).
-type t20() :: [t19(), ...].
-type t21() :: tuple().
-type t21(A) :: A.
@@ -110,7 +130,28 @@
(t24()) -> t24() when is_subtype(t24(), atom()),
is_subtype(t24(), t14()),
is_subtype(t24(), t4()).
+
+-spec over(I :: integer()) -> R1 :: foo:typen();
+ (A :: atom()) -> R2 :: foo:atomen();
+ (T :: tuple()) -> R3 :: bar:typen().
+
-spec mod:t2() -> any().
+
+-spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
+
+-spec handle_cast(Cast ::
+ {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
+
+
+-spec get_closest_pid(term()) ->
+ Return :: pid()
+ | {'error', {'no_process', term()}
+ | {'no_such_group', term()}}.
+
-opaque attributes_data() ::
[{'column', column()} | {'line', info_line()} |
{'text', string()}] | {line(),column()}.
@@ -277,7 +318,10 @@ indent_basics(X, Y, Z)
c
),
-
+ call(2#42423 bor
+ #4234,
+ 2#5432,
+ other_arg),
ok;
indent_basics(Xlongname,
#struct{a=Foo,
@@ -359,7 +403,7 @@ indent_icr(Z) -> % icr = if case receive
X = 43 div 4,
foo(X)
end,
- receive
+ receive
{Z,_,_} ->
X = 43 div 4,
foo(X);
@@ -491,7 +535,7 @@ indent_catch() ->
B = catch oskar(X),
A = catch (baz +
- bax),
+ bax),
catch foo(),
C = catch B +
diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig
index 773998a4c6..9b4203120b 100644
--- a/lib/tools/emacs/test.erl.orig
+++ b/lib/tools/emacs/test.erl.orig
@@ -44,6 +44,24 @@
b
}).
+-record(record3, {a = 8#42423 bor
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+234,
+ d}).
+
+-record(record4, {
+ a = 8#42423 bor
+ 8#4234,
+ b = 8#5432
+ bor 2#1010101
+ c = 123 +
+ 234,
+ d}).
+
+
-define(MACRO_1, macro).
-define(MACRO_2(_), macro).
@@ -51,8 +69,10 @@
-type ann() :: Var :: integer().
-type ann2() :: Var ::
- 'return' | 'return_white_spaces' | 'return_comments'
- | 'text' | ann().
+ 'return'
+ | 'return_white_spaces'
+ | 'return_comments'
+ | 'text' | ann().
-type paren() ::
(ann2()).
-type t1() :: atom().
@@ -110,7 +130,28 @@ t15(),t20(),t21(), t22(),t25()}.
(t24()) -> t24() when is_subtype(t24(), atom()),
is_subtype(t24(), t14()),
is_subtype(t24(), t4()).
+
+-spec over(I :: integer()) -> R1 :: foo:typen();
+ (A :: atom()) -> R2 :: foo:atomen();
+ (T :: tuple()) -> R3 :: bar:typen().
+
-spec mod:t2() -> any().
+
+-spec handle_cast(Cast :: {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
+
+-spec handle_cast(Cast ::
+ {'exchange', node(), [[name(),...]]}
+ | {'del_member', name(), pid()},
+ #state{}) -> {'noreply', #state{}}.
+
+
+-spec get_closest_pid(term()) ->
+ Return :: pid()
+ | {'error', {'no_process', term()}
+ | {'no_such_group', term()}}.
+
-opaque attributes_data() ::
[{'column', column()} | {'line', info_line()} |
{'text', string()}] | {line(),column()}.
@@ -277,7 +318,10 @@ Y =:= 4711 ->
c
),
-
+ call(2#42423 bor
+ #4234,
+ 2#5432,
+ other_arg),
ok;
indent_basics(Xlongname,
#struct{a=Foo,
diff --git a/lib/tools/src/cover.erl b/lib/tools/src/cover.erl
index aff3927db3..1a7ebdc69a 100644
--- a/lib/tools/src/cover.erl
+++ b/lib/tools/src/cover.erl
@@ -1685,8 +1685,8 @@ munge_expr({lc,Line,Expr,Qs}, Vars) ->
{MungedQs, Vars3} = munge_qualifiers(Qs, Vars2),
{{lc,Line,MungedExpr,MungedQs}, Vars3};
munge_expr({bc,Line,Expr,Qs}, Vars) ->
- {bin,BLine,[{bin_element,EL,Val,Sz,TSL}]} = Expr,
- Expr2 = {bin,BLine,[{bin_element,EL,?BLOCK1(Val),Sz,TSL}]},
+ {bin,BLine,[{bin_element,EL,Val,Sz,TSL}|Es]} = Expr,
+ Expr2 = {bin,BLine,[{bin_element,EL,?BLOCK1(Val),Sz,TSL}|Es]},
{MungedExpr,Vars2} = munge_expr(Expr2, Vars),
{MungedQs, Vars3} = munge_qualifiers(Qs, Vars2),
{{bc,Line,MungedExpr,MungedQs}, Vars3};
diff --git a/lib/tools/vsn.mk b/lib/tools/vsn.mk
index 644e8b719b..13cf5af9f5 100644
--- a/lib/tools/vsn.mk
+++ b/lib/tools/vsn.mk
@@ -16,4 +16,4 @@
#
# %CopyrightEnd%
-TOOLS_VSN = 2.6.5
+TOOLS_VSN = 2.6.5.1
diff --git a/lib/wx/api_gen/wxapi.conf b/lib/wx/api_gen/wxapi.conf
index df154f0125..4a646650ea 100644
--- a/lib/wx/api_gen/wxapi.conf
+++ b/lib/wx/api_gen/wxapi.conf
@@ -985,7 +985,9 @@
{class, wxFileDialog, wxDialog, [{skip, [{wxFileDialog,0}]}],
['wxFileDialog','~wxFileDialog','GetDirectory','GetFilename',
{'GetFilenames',[{"files", out}]},
- 'GetFilterIndex','GetMessage','GetPath','GetPaths','GetWildcard',
+ 'GetFilterIndex','GetMessage','GetPath',
+ {'GetPaths', [{"paths", out}]},
+ 'GetWildcard',
'SetDirectory','SetFilename','SetFilterIndex','SetMessage','SetPath',
'SetWildcard']}.
diff --git a/lib/wx/c_src/gen/wxe_funcs.cpp b/lib/wx/c_src/gen/wxe_funcs.cpp
index cb662fc91b..ccbacce9b9 100644
--- a/lib/wx/c_src/gen/wxe_funcs.cpp
+++ b/lib/wx/c_src/gen/wxe_funcs.cpp
@@ -20582,19 +20582,11 @@ case wxFileDialog_GetPath: { // wxFileDialog::GetPath
break;
}
case wxFileDialog_GetPaths: { // wxFileDialog::GetPaths
- wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
- int * pathsLen = (int *) bp; bp += 4;
wxArrayString paths;
- int pathsASz = 0, * pathsTemp;
- for(int i=0; i < *pathsLen; i++) {
- pathsTemp = (int *) bp; bp += 4;
- paths.Add(wxString(bp, wxConvUTF8));
- bp += *pathsTemp;
- pathsASz += *pathsTemp+4;
- }
- bp += (8-((0+ pathsASz) & 7 )) & 7;
+ wxFileDialog *This = (wxFileDialog *) getPtr(bp,memenv); bp += 4;
if(!This) throw wxe_badarg(0);
This->GetPaths(paths);
+ rt.add(paths);
break;
}
case wxFileDialog_GetWildcard: { // wxFileDialog::GetWildcard
diff --git a/lib/wx/configure.in b/lib/wx/configure.in
index 7dc8d6e831..2b47f86baa 100755
--- a/lib/wx/configure.in
+++ b/lib/wx/configure.in
@@ -1,3 +1,21 @@
+dnl Process this file with autoconf to produce a configure script. -*-m4-*-
+
+dnl %CopyrightBegin%
+dnl
+dnl Copyright Ericsson AB 2008-2009. All Rights Reserved.
+dnl
+dnl The contents of this file are subject to the Erlang Public License,
+dnl Version 1.1, (the "License"); you may not use this file except in
+dnl compliance with the License. You should have received a copy of the
+dnl Erlang Public License along with this software. If not, it can be
+dnl retrieved online at http://www.erlang.org/.
+dnl
+dnl Software distributed under the License is distributed on an "AS IS"
+dnl basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+dnl the License for the specific language governing rights and limitations
+dnl under the License.
+dnl
+dnl %CopyrightEnd%
AC_INIT()
@@ -101,7 +119,7 @@ AC_SUBST(MIXED_CYGWIN)
## Check that we are in 32 bits mode on darwin
## (wxWidgets require that it currently uses 32-bits Carbon)
## Otherwise skip building wxErlang
-AC_CHECK_SIZEOF(void *, 4)
+AC_CHECK_SIZEOF(void *)
case $ac_cv_sizeof_void_p-$host_os in
8-darwin*)
diff --git a/lib/wx/doc/src/Makefile b/lib/wx/doc/src/Makefile
index d18daa753a..fd9f7441a3 100644
--- a/lib/wx/doc/src/Makefile
+++ b/lib/wx/doc/src/Makefile
@@ -31,12 +31,6 @@ GenMods = $(shell ls ../../src/gen | grep 'wx[A-Z].*\.erl') \
glu.erl \
gl.erl
-# GenMods = \
-# wx_misc.erl \
-# glu.erl \
-# gl.erl
-
-
ModsNoExt = $(ErlMods:%.erl=%) $(GenMods:%.erl=%)
ifneq ($(INSIDE_ERLSRC),true)
@@ -126,9 +120,9 @@ gifs: $(GIF_FILES:%=$(HTMLDIR)/%)
xml: $(XML_REF3_FILES) $(XML_CHAPTER_FILES)
-ref_man.xml: ref_man.src.xml
+ref_man.xml: ref_man.xml.src
@echo Preparing ref_man.xml
- @cat ref_man.src.xml > ref_man.xml
+ @cat ref_man.xml.src > ref_man.xml
@for d in $(ModsNoExt); do \
echo " <xi:include href=\"$$d.xml\"/>" >> ref_man.xml ; \
done
diff --git a/lib/wx/doc/src/ref_man.src.xml b/lib/wx/doc/src/ref_man.xml.src
index 77fd16b050..77fd16b050 100644
--- a/lib/wx/doc/src/ref_man.src.xml
+++ b/lib/wx/doc/src/ref_man.xml.src
diff --git a/lib/wx/src/gen/wxFileDialog.erl b/lib/wx/src/gen/wxFileDialog.erl
index 22b39aa150..efe1ff57f3 100644
--- a/lib/wx/src/gen/wxFileDialog.erl
+++ b/lib/wx/src/gen/wxFileDialog.erl
@@ -31,7 +31,7 @@
-module(wxFileDialog).
-include("wxe.hrl").
-export([destroy/1,getDirectory/1,getFilename/1,getFilenames/1,getFilterIndex/1,
- getMessage/1,getPath/1,getPaths/2,getWildcard/1,new/1,new/2,setDirectory/2,
+ getMessage/1,getPath/1,getPaths/1,getWildcard/1,new/1,new/2,setDirectory/2,
setFilename/2,setFilterIndex/2,setMessage/2,setPath/2,setWildcard/2]).
%% inherited exports
@@ -152,15 +152,12 @@ getPath(#wx_ref{type=ThisT,ref=ThisRef}) ->
wxe_util:call(?wxFileDialog_GetPath,
<<ThisRef:32/?UI>>).
-%% @spec (This::wxFileDialog(), Paths::[[string()]]) -> ok
+%% @spec (This::wxFileDialog()) -> [[string()]]
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfiledialog.html#wxfiledialoggetpaths">external documentation</a>.
-getPaths(#wx_ref{type=ThisT,ref=ThisRef},Paths)
- when is_list(Paths) ->
+getPaths(#wx_ref{type=ThisT,ref=ThisRef}) ->
?CLASS(ThisT,wxFileDialog),
- Paths_UCA = [unicode:characters_to_binary([PathsTemp,0]) ||
- PathsTemp <- Paths],
- wxe_util:cast(?wxFileDialog_GetPaths,
- <<ThisRef:32/?UI,(length(Paths_UCA)):32/?UI, (<< <<(byte_size(UC_Str)):32/?UI, UC_Str/binary>>|| UC_Str <- Paths_UCA>>)/binary, 0:(((8- ((0 + lists:sum([byte_size(S)+4||S<-Paths_UCA])) band 16#7)) band 16#7))/unit:8>>).
+ wxe_util:call(?wxFileDialog_GetPaths,
+ <<ThisRef:32/?UI>>).
%% @spec (This::wxFileDialog()) -> string()
%% @doc See <a href="http://www.wxwidgets.org/manuals/stable/wx_wxfiledialog.html#wxfiledialoggetwildcard">external documentation</a>.
diff --git a/make/otp_release_targets.mk b/make/otp_release_targets.mk
index b6e1f4195e..2cba32e82c 100644
--- a/make/otp_release_targets.mk
+++ b/make/otp_release_targets.mk
@@ -1,24 +1,21 @@
-# ``The contents of this file are subject to the Erlang Public License,
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
+# 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.
#
-# 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$
-
-# ----------------------------------------------------
-# Target for building only the files needed by the Book generation
-# ----------------------------------------------------
-#texmake: $(TEX_FILES) $(PSFIG_FILES)
+# %CopyrightEnd%
+#
# ----------------------------------------------------
# Targets for the new documentation support
@@ -48,6 +45,26 @@ $(HTMLDIR)/users_guide.html: $(XML_FILES)
-path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_pdf.xsl book.xml > $@
+
+# ------------------------------------------------------------------------
+# The following targets just exist in the documentation directory
+# ------------------------------------------------------------------------
+ifneq ($(XML_FILES),)
+
+# ----------------------------------------------------
+# Generation of application index data
+# ----------------------------------------------------
+$(HTMLDIR)/$(APPLICATION).eix: $(XML_FILES)
+ date=`date +"%B %e %Y"`; \
+ $(XSLTPROC) --stringparam docgen "$(DOCGEN)" \
+ --stringparam gendate "$$date" --stringparam appname "$(APPLICATION)" --stringparam appver "$(VSN)" --xinclude \
+ -path $(DOCGEN)/priv/docbuilder_dtd -path $(DOCGEN)/priv/dtd_html_entities $(DOCGEN)/priv/xsl/db_eix.xsl book.xml > $@
+
+docs: $(HTMLDIR)/$(APPLICATION).eix
+
+# ----------------------------------------------------
+# Local documentation target for testing
+# ----------------------------------------------------
local_docs: TOPDOCDIR=.
local_docs: docs
$(INSTALL) $(DOCGEN)/priv/css/otp_doc.css $(HTMLDIR)
@@ -59,6 +76,7 @@ local_docs: docs
$(DOCGEN)/priv/js/flipmenu/flip_static.gif \
$(DOCGEN)/priv/js/flipmenu/flipmenu.js $(HTMLDIR)/js/flipmenu
+endif
# ----------------------------------------------------
# Standard release target
@@ -73,6 +91,6 @@ release release_docs release_tests release_html:
else
release release_docs release_tests release_html:
- $(MAKE) $(MFLAGS) RELEASE_PATH=$(TESTROOT) $(TARGET_MAKEFILE) $@_spec
+ $(MAKE) $(MFLAGS) RELEASE_PATH=$(TESTROOT) $(TARGET_MAKEFILE) $@_spec
endif
diff --git a/make/otp_subdir.mk b/make/otp_subdir.mk
index 46c61c9e54..bfbd9997a1 100644
--- a/make/otp_subdir.mk
+++ b/make/otp_subdir.mk
@@ -1,30 +1,30 @@
-# ``The contents of this file are subject to the Erlang Public License,
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 1997-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
# compliance with the License. You should have received a copy of the
# Erlang Public License along with this software. If not, it can be
-# retrieved via the world wide web at http://www.erlang.org/.
+# 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.
#
-# 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$
-#
+# %CopyrightEnd%
#
# Make include file for otp
-.PHONY: debug opt release local_docs docs release_docs tests release_tests \
+.PHONY: debug opt release docs release_docs tests release_tests \
clean depend valgrind
#
# Targets that don't affect documentation directories
#
-debug opt release local_docs docs release_docs tests release_tests clean depend valgrind:
+opt debug release docs release_docs tests release_tests clean depend valgrind:
@set -e ; \
app_pwd=`pwd` ; \
if test -f vsn.mk; then \
diff --git a/otp_build b/otp_build
index e478256314..cddb477db5 100755
--- a/otp_build
+++ b/otp_build
@@ -1,4 +1,22 @@
#! /bin/sh
+#
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2002-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# Software distributed under the License is distributed on an "AS IS"
+# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+# the License for the specific language governing rights and limitations
+# under the License.
+#
+# %CopyrightEnd%
+#
# Expected autoconf version
EXPECTED_AUTOCONF_VERSION=2.59
@@ -69,52 +87,83 @@ usage ()
echo " cancel_preloaded - uncheckout preloaded code (only in Clearcase)"
}
+export_cross_env ()
+{
+ if [ "x$ERL_XCOMP_CONF" != "x" ]; then
+ export erl_xcomp_host
+ export erl_xcomp_configure_flags
+ export erl_xcomp_cc
+ export erl_xcomp_ld
+ export erl_xcomp_cflags
+ export erl_xcomp_cpp
+ export erl_xcomp_ldflags
+ export erl_xcomp_ranlib
+ export erl_xcomp_ar
+ export erl_xcomp_ded_ld
+ export erl_xcomp_ded_ldflags
+ export erl_xcomp_ded_ld_runtime_library_path
+ export erl_xcomp_bigendian
+ export erl_xcomp_linux_clock_gettime_correction
+ export erl_xcomp_linux_nptl
+ export erl_xcomp_linux_usable_sigusrx
+ export erl_xcomp_linux_usable_sigaltstack
+ export erl_xcomp_poll
+ export erl_xcomp_kqueue
+ export erl_xcomp_putenv_copy
+ export erl_xcomp_reliable_fpe
+ export erl_xcomp_getaddrinfo
+ export erl_xcomp_gethrvtime_procfs_ioctl
+ export erl_xcomp_clock_gettime
+ export erl_xcomp_after_morecore_hook
+ export erl_xcomp_dlsym_brk_wrappers
+ fi
+}
+
xcomp_fail ()
{
- echo "The mandatory cross compilation variable" $1 "is not set in" $2 ",aborting" >&2
+ echo "The mandatory cross compilation variable '"$1"' is not set, aborting..." >&2
exit 1
}
-check_xcomp_file ()
+source_xcomp_file ()
{
- if test "x$erl_xcomp_os" = "x"; then
- xcomp_fail erl_xcomp_os $1
- fi
- if test "x$erl_xcomp_hw" = "x"; then
- xcomp_fail erl_xcomp_hw $1
- fi
- if test "x$erl_xcomp_man" = "x"; then
- xcomp_fail erl_xcomp_man $1
- fi
- if test "x$erl_xcomp_target_xtra" = "x"; then
- xcomp_fail erl_xcomp_target_extra $1
- fi
- if test "x$erl_xcomp_void_p" = "x"; then
- xcomp_fail erl_xcomp_void_p $1
- fi
- if test "x$erl_xcomp_short" = "x"; then
- xcomp_fail erl_xcomp_short $1
- fi
- if test "x$erl_xcomp_int" = "x"; then
- xcomp_fail erl_xcomp_int $1
- fi
- if test "x$erl_xcomp_long" = "x"; then
- xcomp_fail erl_xcomp_long $1
- fi
- if test "x$erl_xcomp_long_long" = "x"; then
- xcomp_fail erl_xcomp_long_long $1
+ case x$1 in
+ x/*)
+ ;;
+ x)
+ echo "env_cross requires path to cross compilation configuration" >&2
+ exit 1;;
+ x*)
+ echo "An absoulute path to the cross compilation file is required: $1" >&2
+ exit 1;;
+ esac
+
+ if [ ! -f $1 ]; then
+ echo "No such file: $1" >&2
+ exit 1
fi
- if test "x$erl_xcomp_sizeof_size_t" = "x"; then
- xcomp_fail erl_xcomp_sizeof_size_t $1
+
+ . $1
+}
+
+finalize_xcomp_conf ()
+{
+ if test "x$erl_xcomp_host" = "x"; then
+ xcomp_fail erl_xcomp_host
fi
- if test "x$erl_xcomp_sizeof_off_t" = "x"; then
- xcomp_fail erl_xcomp_sizeof_off_t $1
+
+ if test "x$erl_xcomp_target" != "x"; then
+ echo "The 'erl_xcomp_target' configuration variable should no longer be used." >&2
+ echo "For more information see the xcomp/README file." >&2
+ exit 1;
fi
- if test "x$erl_xcomp_os" = "xlinux"; then
- if test "x$erl_xcomp_linux_kernel" = "x"; then
- xcomp_fail erl_xcomp_linux_kernel $1
- fi
+
+ OVERRIDE_TARGET=`$ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host`
+ if test $? -ne 0; then
+ exit $?
fi
+ TARGET=$OVERRIDE_TARGET
+
return 0
}
@@ -342,17 +391,21 @@ do_configure ()
# compilers. It's a kludge, but a working one...
#
- crossdirs="erts lib/common_test lib/erl_interface lib/gs lib/megaco lib/odbc lib/snmp lib/wx"
-
if [ -z "$ONLY_ERTS" ]; then
- for x in $crossdirs; do
- if [ -f "$x/configure" ]; then
- (cd $x;./configure --host=$erl_xcomp_hw --with-xcompconf=$ERL_XCOMP_CONF $CONFIG_FLAGS) || exit 1
- fi
- done
+ crossdirs="erts lib/common_test lib/erl_interface lib/gs lib/megaco lib/odbc lib/snmp lib/wx"
else
- (cd $ERL_TOP/erts;./configure --host=$erl_xcomp_hw --with-xcompconf=$ERL_XCOMP_CONF $CONFIG_FLAGS) || exit 1
+ crossdirs="erts"
fi
+
+ export_cross_env
+
+ for d in $crossdirs; do
+ echo "== Entering $d =="
+ echo "./configure --build=$BUILDSYS --host=$erl_xcomp_host $CONFIG_FLAGS"
+ (cd $ERL_TOP/$d; ./configure --build=$BUILDSYS --host=$erl_xcomp_host $CONFIG_FLAGS) || exit 1
+ echo "== Leaving $d =="
+ done
+
CC="$save_CC"
LD="$save_LD"
CFLAGS="$save_CFLAGS"
@@ -551,20 +604,11 @@ echo_env_vxworks ()
echo_env_cross ()
{
- if [ -z "$1" ]; then
- echo "env_cross requires path to cross compilation configuration" >&2
- exit 1
- fi
-
- if [ ! -f $1 ]; then
- echo "No such file: $1" >&2
- exit 1
- fi
- . $1
- check_xcomp_file $1
+ source_xcomp_file $1
+ finalize_xcomp_conf
echo_env_erltop
echo_setenv ERL_XCOMP_CONF $1 ';'
- echo_setenv OVERRIDE_TARGET $erl_xcomp_target
+ echo_setenv OVERRIDE_TARGET $OVERRIDE_TARGET
echo_envinfo
}
@@ -863,7 +907,7 @@ do_prepare_prel ()
(cd $ERL_TOP/erts/preloaded/src && $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET prepare) || exit 1
echo '*****************************************************'
echo "Prepared for new preloaded code build - "
- echo "Directory ERL_TOP/erts/prelaoded/ebin completely"
+ echo "Directory ERL_TOP/erts/preloaded/ebin completely"
echo "checked out."
echo '*****************************************************'
}
@@ -941,9 +985,10 @@ do_boot_cross ()
TARGET=`$ERL_TOP/erts/autoconf/config.guess`
$MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET all_bootstraps || exit 1;
- $MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET local_setup || exit 1;
+
TARGET=$SAVE_TARGET
OVERRIDE_TARGET=$SAVE_OVERRIDE_TARGET
+
$MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET libs || exit 1;
$MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET depend || exit 1;
$MAKE MAKE="$MAKE" BOOTSTRAP_ROOT=$BOOTSTRAP_ROOT TARGET=$TARGET emulator || exit 1;
@@ -1131,6 +1176,10 @@ esac
if [ ! -z "$OVERRIDE_TARGET" ]; then
TARGET="$OVERRIDE_TARGET"
+else
+ if [ "x$erl_xcomp_host" != "x" ]; then
+ finalize_xcomp_conf
+ fi
fi
# Setting a bootstrap root is inherently very dangerous now that the bootstrap
diff --git a/system/doc/reference_manual/code_loading.xml b/system/doc/reference_manual/code_loading.xml
index 8861b3bea5..f56e1ff408 100644
--- a/system/doc/reference_manual/code_loading.xml
+++ b/system/doc/reference_manual/code_loading.xml
@@ -117,11 +117,14 @@ loop() ->
</section>
<section>
+ <marker id="on_load"></marker>
<title>Running a function when a module is loaded</title>
<warning>
- <p>This section describes an experimental feature introduced in R13B03.
- There may be backward-incompatible changes in the feature in future releases.</p>
+ <p>This section describes an experimental feature that was
+ introduced in R13B03, and changed in a backwards-incompatible
+ way in R13B04. There may be more backward-incompatible changes
+ in future releases.</p>
</warning>
<p>The <c>-on_load()</c> directive names a function that should
@@ -132,25 +135,35 @@ loop() ->
<p>It is not necessary to export the function. It will be called in a
freshly spawned process (which will be terminated as soon as the function
- returns). The function must return <c>true</c> if the module is to
- be remained loaded and be callable, or <c>false</c> if the module
- is to be unloaded. Returning any other value or generating an exception
- will also cause the module to be unloaded.</p>
+ returns). The function must return <c>ok</c> if the module is to
+ be remained loaded and become callable, or any other value if the module
+ is to be unloaded. Generating an exception will also cause the
+ module to be unloaded. If the return value is not an atom,
+ a warning error report will be sent to the error logger.</p>
<p>A process that calls any function in a module whose <c>on_load</c>
function has not yet returned will be suspended until the <c>on_load</c>
function has returned.</p>
+ <p>In embedded mode, all modules will be loaded first and then
+ will all on_load functions be called. The system will be
+ terminated unless all of the on_load functions return
+ <c>ok</c></p>.
+
<p>Example:</p>
<pre>
-module(m).
--on_load(run_me/0).
+-on_load(load_my_nifs/0).
+
+load_my_nifs() ->
+ NifPath = ..., %Set up the path to the NIF library.
+ Info = ..., %Initialize the Info term
+ erlang:load_nif(NifPath, Info).</pre>
-run_me() ->
- %% Do something with side effects here, for instance load a library
- %% containing native-implemented functions.
- true.</pre>
+ <p>If the call to <c>erlang:load_nif/2</c> fails, the module
+ will be unloaded and there will be warning report sent to
+ the error loader.</p>
</section>
diff --git a/system/doc/reference_manual/modules.xml b/system/doc/reference_manual/modules.xml
index 8b14ca3459..f4885be480 100644
--- a/system/doc/reference_manual/modules.xml
+++ b/system/doc/reference_manual/modules.xml
@@ -167,6 +167,21 @@ fact(0) -> % |
the original user-written file from which the source program
was produced.</p>
</section>
+
+ <section>
+ <title>Types and function specifications</title>
+ <p>The current release implements types and function specifications
+ as described in
+ <url href="http://www.erlang.org/eeps/eep-0008.html">EEP8 -
+Types and function specifications</url>.
+
+ <note>
+ <p>The implementation and EEP8 may not exactly correspond to
+ each other. In a future release, type and function specifications
+ will be described in this reference manual.</p>
+ </note>
+ </p>
+ </section>
</section>
<section>
diff --git a/xcomp/README b/xcomp/README
new file mode 100644
index 0000000000..dfda81fc8e
--- /dev/null
+++ b/xcomp/README
@@ -0,0 +1,218 @@
+================================================================================
+ Cross compiling Erlang/OTP
+================================================================================
+
+%CopyrightBegin%
+
+Copyright Ericsson AB 2009. All Rights Reserved.
+
+The contents of this file are subject to the Erlang Public License,
+Version 1.1, (the "License"); you may not use this file except in
+compliance with the License. You should have received a copy of the
+Erlang Public License along with this software. If not, it can be
+retrieved online at http://www.erlang.org/.
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+the License for the specific language governing rights and limitations
+under the License.
+
+%CopyrightEnd%
+
+================================================================================
+
+This directory contains a configuration file template and configuration examples
+for cross compiling Erlang/OTP. The configuration files contain configuration
+variables and should be supplied to the $ERL_TOP/otp_build when setting up an
+appropriate environment for cross compiling. The currently used configuration
+variables are described later in this document.
+
+The erl-xcomp.conf.template contains all available configuration variables
+and can be used as a template when creating a configuration. See the
+erl-xcomp-TileraMDE2.0-tilepro.conf for an example of a working configuration
+file.
+
+Instead of using the configuration files one can export the configuration
+variables as ordinary environment variables before calling otp_build. If
+default behavior of a variable is satisfactory, the variable need not to
+be set and exported.
+
+Note that the support for cross compiling is in its early stage of development,
+and should be considered as experimental. The build system including cross
+compilation configuration variables used may be subject to non backward
+compatible changes without prior notice. It works for cross compiling some
+Linux/GNU systems, but has only been partly tested for more esoteric platforms.
+The VxWorks example file is highly dependent on our environment and is here
+more or less only for internal use.
+
+Please submit any patches for cross compiling in a way consistent with this
+system. If a new configuration variable is needed for your system, add it to the
+template file, use it in otp_build, aclocal.m4 and/or configure.in. All input is
+welcome as we cannot possibly have all cross compiling environments out there to
+test with.
+
+General information on how to submit patches can be found at:
+ http://wiki.github.com/erlang/otp/submitting-patches
+
+== Build and Install ===========================================================
+
+ [1] $ cd $ERL_TOP
+
+Either set up your cross compilation variables in the environment manually,
+or set up the environment using a configuration file by executing:
+ [2] $ eval `./otp_build env_cross <ABSOLUTE_PATH_TO_XCONF_FILE>`
+
+Configure and build Erlang/OTP:
+ [3] $ ./otp_build configure
+ [4] $ ./otp_build boot -a
+ [5] $ ./otp_build release -a <ABSOLUTE_PATH_TO_RELEASE_ROOT>
+
+The Install script used when installing Erlang/OTP requires common Unix
+tools such as 'sed' to be present in your PATH. If your target system
+does not have such tools, you need to run the Install script on your
+build machine before packing Erlang/OTP. If so, run the Install script
+like follows; otherwise skip [6] and [7]:
+ [6] $ cd <ABSOLUTE_PATH_TO_RELEASE_ROOT>
+ [7] $ ./Install -cross <ABSOLUTE_INSTALL_ROOT_ON_TARGET> # answer questions
+
+Pack Erlang/OTP as follows (gnu tar is assumed):
+ [8] $ cd <ABSOLUTE_PATH_TO_RELEASE_ROOT>
+ [9] $ tar -zcf <WHERE_TO_SAVE_THE_RELEASE>/<RELEASE_NAME>.tar.gz *
+
+Install Erlang/OTP on the target system like follows. If you ran the Install
+script before packing ([6] and [7]) you should skip [12]:
+ [10] $ cd <ABSOLUTE_INSTALL_ROOT_ON_TARGET>
+ [11] $ tar -zxf <WHERE_THE_PACKED_RELEASE_EXIST>/<RELEASE_NAME>.tar.gz
+ [12] $ ./Install <ABSOLUTE_INSTALL_ROOT_ON_TARGET> # answer questions
+
+<ABSOLUTE_INSTALL_ROOT_ON_TARGET> usually equals current working directory
+when you run the Install script on the target system, but does not have to.
+It can follow another path through the file system to the same directory.
+<ABSOLUTE_INSTALL_ROOT_ON_TARGET> is the path that will be used when running
+Erlang/OTP and is the path that have to be available at run time.
+
+== Currently used configuration variables ======================================
+
+-- Mandatory -------------------------------------------------------------------
+
+* erl_xcomp_host
+ Target system. The value will be passed as '--host' argument to the configure
+ script. It does not have to be a full CPU-VENDOR-OS triplet, but can be. The
+ full CPU-VENDOR-OS triplet will be created by:
+ $ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host
+
+-- Optional --------------------------------------------------------------------
+
+* erl_xcomp_configure_flags
+ To override the configure flags for a special target system, you
+ can set this variable which overrides configure parameters on the
+ command line and instead uses the specified options. The variable
+ leaves the build-host system untouched.
+
+-- Optional build environment flags --
+
+If the cross compilation tools aren't prefixed by '$erl_xcomp_host-',
+you will have to use these configuration variables in order to use the
+right cross compilation tools.
+
+* erl_xcomp_cc
+ C compiler.
+
+* erl_xcomp_ld
+ Linker.
+
+* erl_xcomp_cflags
+ C compiler flags.
+
+* erl_xcomp_cpp
+ C pre processor.
+
+* erl_xcomp_ldflags
+ Linker flags.
+
+* erl_xcomp_ranlib
+ Ranlib program.
+
+* erl_xcomp_ar
+ Ar program.
+
+* erl_xcomp_ded_ld
+ Dynamic Erlang Driver linker.
+
+* erl_xcomp_ded_ldflags
+ Dynamic Erlang Driver linker flags.
+
+* erl_xcomp_ded_ld_runtime_library_path
+ Dynamic Erlang Driver runtime linker path.
+
+-- Optional feature, or bug tests --
+
+These tests cannot (always) be done automatically when cross compiling. You
+usually does not need to set these variables. Only set these if you really
+know what you are doing.
+
+* erl_xcomp_bigendian - yes|no
+ If yes, the target system must be big endian. If no, little endian. This can
+ often be automatically detected, but not always. If not automatically
+ detected, configure will fail unless this variable is set. No default value
+ is used, i.e., configure will try to figure this out automatically.
+
+* erl_xcomp_linux_clock_gettime_correction - yes|no (defaults to yes)
+ If yes, clock_gettime(CLOCK_MONOTONIC, _) on the target system must work.
+ This variable is recommended to be set to no on Linux systems with kernel
+ versions less than 2.6.
+
+* erl_xcomp_linux_nptl - yes|no (defaults to yes on Linux; otherwise, no)
+ If yes, the target system must have NPTL (Native POSIX Thread Library).
+ Older Linux systems have LinuxThreads instead of NPTL (Linux kernel
+ versions typically less than 2.6).
+
+* erl_xcomp_linux_usable_sigusrx - yes|no (defaults to yes)
+ If yes, the SIGUSR1 and SIGUSR2 must be usable by the ERTS. Old
+ LinuxThreads thread libraries (Linux kernel versions less than 2.2) used
+ these signals and made them unusable by the ERTS.
+
+* erl_xcomp_linux_usable_sigaltstack - yes|no (defaults to yes)
+ If yes, sigaltstack() must be usable on the target system. sigaltstack()
+ on Linux kernel versions less than 2.4 are broken.
+
+* erl_xcomp_poll - yes|no (defaults to no on Darwin/MacOSX; otherwise, yes)
+ If yes, the target system must have a working poll() implementation that also
+ can handle devices. If no, select() will be used instead of poll().
+
+* erl_xcomp_kqueue - yes|no (defaults to no)
+ If yes, the target system must have a working kqueue() implementation that
+ returns a file descriptor which can be used by poll() and/or select().
+ If no and the target system has not got epoll() or /dev/poll, the kernel-poll
+ feature will be disabled.
+
+* erl_xcomp_putenv_copy - yes|no (defaults to no)
+ If yes, the target system must have a putenv() implementation that stores a
+ copy of the key/value pair.
+
+* erl_xcomp_reliable_fpe - yes|no (defaults to no)
+ If yes, the target system must have reliable floating point exceptions.
+
+* erl_xcomp_getaddrinfo - yes|no (defaults to no)
+ If yes, the target system must have a working getaddrinfo() implementation
+ that can handle both IPv4 and IPv6.
+
+* erl_xcomp_gethrvtime_procfs_ioctl - yes|no (defaults to no)
+ If yes, the target system must have a working gethrvtime() implementation
+ and is used with procfs ioctl().
+
+* erl_xcomp_clock_gettime - yes|no (defaults to no)
+ If yes, the target system must have a working clock_gettime() implementation
+ that can be used for retrieving process CPU time.
+
+* erl_xcomp_after_morecore_hook - yes|no (defaults to no)
+ If yes, the target system must have a working __after_morecore_hook that can
+ be used for tracking used malloc() implementations core memory usage.
+
+* erl_xcomp_dlsym_brk_wrappers - yes|no (defaults to no)
+ If yes, the target system must have a working dlsym(RTLD_NEXT, <S>)
+ implementation that can be used on 'brk' and 'sbrk' symbols used by the
+ malloc() implementation in use, and by this track the malloc() implementations
+ core memory usage.
+
+================================================================================
diff --git a/xcomp/README.xcomp b/xcomp/README.xcomp
deleted file mode 100644
index 4df9226a96..0000000000
--- a/xcomp/README.xcomp
+++ /dev/null
@@ -1,25 +0,0 @@
-This directory contains configuration file templates and examples for
-cross compiling Erlang/OTP. The configuration files should be supplied to
-$ERl_TOP/otp_build in the ./otp_build env_cross command to set up an
-appropriate environment for cross compiling.
-
-Copy the template file erl-xcomp.conf.template to an appropriate name
-and fill in at least the mandatory parts before attempting cross
-compilation. See the template file for details on configuration
-parameters and see the example erl-xcomp-TileraMDE2.0-tilepro.conf for
-an example of a working configuration file.
-
-The support for cross compiling is in it's early stage of development,
-it works for cross compiling some gnu/linux systems, but has only been partly
-tested for more esotheric platforms. The vxworks example file is highly
-dependent on our environment and is here more or less for internal use.
-
-Please submit any patches for cross compiling in a way consistent with
-this system. Variables should be added to the configuration file,
-which is sourced both by $ERL_TOP/otp_build and each configure
-script. If a new configuration variable is needed for your system, add
-it to the template file, use it in otp_build and/or configure and
-submit the patch to erlang-patches for further integration into the
-main branch. All input is welcome as we cannot possibly have all cross
-compiling environments out there to test with.
-
diff --git a/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf b/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
index e711f06a27..c8e7212e1f 100644
--- a/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
+++ b/xcomp/erl-xcomp-TileraMDE2.0-tilepro.conf
@@ -16,73 +16,43 @@
###
### %CopyrightEnd%
###
-### File: erl-xcomp.conf
+### File: erl-xcomp-TileraMDE2.0-tilepro.conf
### Author: Rickard Green
###
### ----------------------------------------------------------------------------
### When cross compiling Erlang/OTP, copy this file and set the variables
### needed below. Then pass the path to the copy of this file as an argument
-### to "eval `otp_build env_cross <path to erl-xcomp.conf file>`".
+### to "eval `otp_build env_cross <absolute path to erl-xcomp.conf file>`".
### ----------------------------------------------------------------------------
### ----------------------------------------------------------------------------
### Variables in the following section *have* to be set.
###
-##
-## Operating system and hardware architecture.
-##
-# Operating system: linux|solaris<ver>|darwin|freebsd|win32|<...>
-erl_xcomp_os=linux
-# Hardware architecture: x86|x86_64|ultrasparc|sparc64|ppc|arm|tile|<...>
-erl_xcomp_hw=tile
-# Manufacturer: (unknown is ok)
-erl_xcomp_man=tilera
-# Extra target info (unknown is ok)
-erl_xcomp_target_xtra=gnu
-
-# Target (change if default isn't satisfactory)
-erl_xcomp_target=${erl_xcomp_hw}-${erl_xcomp_man}-${erl_xcomp_os}-${erl_xcomp_target_xtra}
##
-## Sizes (in bytes) of some important types.
+## Target system. The value will be passed as '--host' argument to the configure
+## script. It does not have to be a full CPU-VENDOR-OS tripplet, but can be. The
+## full CPU-VENDOR-OS tripplet will be created by:
+## $ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host
##
-# void *
-erl_xcomp_void_p=4
-# short
-erl_xcomp_short=2
-# int
-erl_xcomp_int=4
-# long
-erl_xcomp_long=4
-# long long (use 0 if no 'long long' type exist)
-erl_xcomp_long_long=8
-# size_t
-erl_xcomp_sizeof_size_t=4
-# off_t
-erl_xcomp_sizeof_off_t=4
+erl_xcomp_host=tile
### ----------------------------------------------------------------------------
-### The variables in the following section have to be set for linux systems
-###
-# linux kernel version (as reported by "uname -r")
-erl_xcomp_linux_kernel=2.6.26.7
-
### ----------------------------------------------------------------------------
-### ---------------------------------------------------------------------------
### To override the configure flags for a special target system, You
### can set this variable which overrides configure parameters on the
### command line and instead uses the specified options. The variable
### leaves the build-host system untouched.
-### ---------------------------------------------------------------------------
+### ----------------------------------------------------------------------------
erl_xcomp_configure_flags="--without-termcap"
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
### You can specify a specific CC or LD for the build target (the cross
### compiler) here along with magic CFLAGS and/or LDFLAGS if needed
### ar and ranlib might also be specified if needed.
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
erl_xcomp_cc=
@@ -98,7 +68,7 @@ erl_xcomp_ranlib=
erl_xcomp_ar=
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
### The ded_ls and ded_ldflags variables control linking of dynamically loaded
### erlang drivers. On i.e. Linux these are set to
### $(CC) and "-shared" respectively, but other OS'es might need other
@@ -106,7 +76,7 @@ erl_xcomp_ar=
### erl_xcomp_ded_ld_runtime_library_path is the flag to set a
### specific runtime library path for the shared library at link time,
### usually this should be left empty.
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
erl_xcomp_ded_ld=
@@ -114,83 +84,117 @@ erl_xcomp_ded_ldflags=
erl_xcomp_ded_ld_runtime_library_path=
-### The variables in the following section does not need to be set. Only
-### set these if you really know what you are doing.
+###
+### Optional feature, or bug tests
+###
+### These tests cannot (always) be done automatically when cross compiling.
+### You usually does not need to set these variables. Only set these if you
+### really know what you are doing.
###
##
-## Big endian/little endian can usually be determined by configure correctly,
-## but if not, set this variable
-##
+## erl_xcomp_bigendian - yes|no
+## If yes, the target system must be big endian. If no, little endian. This
+## can often be automatically detected, but not always. If not automatically
+## detected, configure will fail unless this variable is set. No default value
+## is used, i.e., configure will try to figure this out automatically.
erl_xcomp_bigendian=
##
-## If you have a working poll that can be used: yes|no
+## erl_xcomp_linux_clock_gettime_correction - yes|no (defaults to yes)
+## If yes, clock_gettime(CLOCK_MONOTONIC, _) on the target system must work.
+## This variable is recommended to be set to no on Linux systems with kernel
+## versions less than 2.6.
+##
+erl_xcomp_linux_clock_gettime_correction=yes
+
+##
+## erl_xcomp_linux_nptl - yes|no (defaults to yes on Linux; otherwise, no)
+## If yes, the target system must have NPTL (Native POSIX Thread Library).
+## Older Linux systems have LinuxThreads instead of NPTL (Linux kernel
+## versions typically less than 2.6).
+##
+erl_xcomp_linux_nptl=yes
+
+##
+## erl_xcomp_linux_usable_sigusrx - yes|no (defaults to yes)
+## If yes, the SIGUSR1 and SIGUSR2 must be usable by the ERTS. Old
+## LinuxThreads thread libraries (Linux kernel versions less than 2.2) used
+## these signals and made them unusable by the ERTS.
+##
+erl_xcomp_linux_usable_sigusrx=yes
+
+##
+## erl_xcomp_linux_usable_sigaltstack - yes|no (defaults to yes)
+## If yes, sigaltstack() must be usable on the target system. sigaltstack()
+## on Linux kernel versions less than 2.4 are broken.
+##
+erl_xcomp_linux_usable_sigaltstack=yes
+
+##
+## erl_xcomp_poll - yes|no (defaults to no on Darwin/MacOSX; otherwise, yes)
+## If yes, the target system must have a working poll() implementation that
+## also can handle devices. If no, select() will be used instead of poll().
##
erl_xcomp_poll=yes
##
-## If you have a working kqueue() that can be used: yes|no
+## erl_xcomp_kqueue - yes|no (defaults to no)
+## If yes, the target system must have a working kqueue() implementation that
+## returns a file descriptor which can be used by poll() and/or select().
+## If no and the target system has not got epoll() or /dev/poll, the
+## kernel-poll feature will be disabled.
##
erl_xcomp_kqueue=
##
-## If you have a putenv() that stores a copy of the key-value pair: yes|no
+## erl_xcomp_putenv_copy - yes|no (defaults to no)
+## If yes, the target system must have a putenv() implementation that stores a
+## copy of the key/value pair.
##
erl_xcomp_putenv_copy=
##
-## If you have reliable floating point exeptions that can be
-## used: yes|no
+## erl_xcomp_reliable_fpe - yes|no (defaults to no)
+## If yes, the target system must have reliable floating point exceptions.
##
erl_xcomp_reliable_fpe=
##
-## If you have getaddrinfo() usable for ipv6: yes|no
+## erl_xcomp_getaddrinfo - yes|no (defaults to no)
+## If yes, the target system must have a working getaddrinfo() implementation
+## that can handle both IPv4 and IPv6.
##
erl_xcomp_getaddrinfo=yes
##
-## If you have a gethrvtime() that works and uses ioctl()
-## to /proc/self: yes|no
+## erl_xcomp_gethrvtime_procfs_ioctl - yes|no (defaults to no)
+## If yes, the target system must have a working gethrvtime() implementation
+## and is used with procfs ioctl().
##
erl_xcomp_gethrvtime_procfs_ioctl=
##
-## If you have a working clock_gettime(): yes|no
+## erl_xcomp_clock_gettime - yes|no (defaults to no)
+## If yes, the target system must have a working clock_gettime()
+## implementation that can be used for retrieving process CPU time.
##
erl_xcomp_clock_gettime=
##
-## If you have a __after_morecore_hook that can track malloc()s
-## core memory use: yes|no
+## erl_xcomp_after_morecore_hook - yes|no (defaults to no)
+## If yes, the target system must have a working __after_morecore_hook that
+## can be used for tracking used malloc() implementations core memory usage.
##
erl_xcomp_after_morecore_hook=
##
-## If you have brk, sbrk and end symbols: yes|no
-##
-# brk
-erl_xcomp_have_brk=
-# _brk
-erl_xcomp_have__brk=
-# __brk
-erl_xcomp_have___brk=
-# sbrk
-erl_xcomp_have_sbrk=
-# _sbrk
-erl_xcomp_have__sbrk=
-# __sbrk
-erl_xcomp_have___sbrk=
-# end
-erl_xcomp_end=
-# _end
-erl_xcomp__end=
-
-##
-## If sbrk/brk wrappers using dlsym(RTLD_NEXT, _) can track malloc()s
-## core memory use: yes|no
+## erl_xcomp_dlsym_brk_wrappers - yes|no (defaults to no)
+## If yes, the target system must have a working dlsym(RTLD_NEXT, <S>)
+## implementation that can be used on 'brk' and 'sbrk' symbols used by the
+## malloc() implementation in use, and by this track the malloc()
+## implementations core memory usage.
##
-erl_xcomp_brk_wrappers=
+erl_xcomp_dlsym_brk_wrappers=
### ----------------------------------------------------------------------------
diff --git a/xcomp/erl-xcomp-vxworks_ppc32.conf b/xcomp/erl-xcomp-vxworks_ppc32.conf
index 544212233a..19a9327239 100644
--- a/xcomp/erl-xcomp-vxworks_ppc32.conf
+++ b/xcomp/erl-xcomp-vxworks_ppc32.conf
@@ -23,7 +23,7 @@
### ----------------------------------------------------------------------------
### When cross compiling Erlang/OTP, copy this file and set the variables
### needed below. Then pass the path to the copy of this file as an argument
-### to "eval `otp_build env_cross <path to erl-xcomp.conf file>`".
+### to "eval `otp_build env_cross <absolute path to erl-xcomp.conf file>`".
### ----------------------------------------------------------------------------
### ----------------------------------------------------------------------------
@@ -31,60 +31,27 @@
###
##
-## Operating system and hardware architecture.
-##
-# Operating system: linux|solaris<ver>|darwin|freebsd|win32|<...>
-erl_xcomp_os=vxworks
-# Hardware architecture: x86|x86_64|ultrasparc|sparc64|ppc|arm|tile|<...>
-# Note that this will be the host parameter to configure, so it
-# should be both recognizable by config.sub and a valid prefix for
-# i.e. gcc etc.
-erl_xcomp_hw=ppc-wrs
-# Manufacturer: (unknown is ok)
-erl_xcomp_man=wrs
-# Extra target info (unknown is ok)
-erl_xcomp_target_xtra=unknown
-
-# Target (change if default isn't satisfactory)
-erl_xcomp_target=powerpc-wrs-vxworks
-
-##
-## Sizes (in bytes) of some important types.
-##
-# void *
-erl_xcomp_void_p=4
-# short
-erl_xcomp_short=2
-# int
-erl_xcomp_int=4
-# long
-erl_xcomp_long=4
-# long long (use 0 if no 'long long' type exist)
-erl_xcomp_long_long=8
-# size_t
-erl_xcomp_sizeof_size_t=4
-# off_t
-erl_xcomp_sizeof_off_t=4
+## Target system. The value will be passed as '--host' argument to the configure
+## script. It does not have to be a full CPU-VENDOR-OS tripplet, but can be. The
+## full CPU-VENDOR-OS tripplet will be created by:
+## $ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host
+##
+erl_xcomp_host=powerpc-wrs-vxworks
### ----------------------------------------------------------------------------
-### The variables in the following section have to be set for linux systems
-###
-# linux kernel version (as reported by "uname -r")
-erl_xcomp_linux_kernel=
-
### ----------------------------------------------------------------------------
-### ---------------------------------------------------------------------------
### To override the configure flags for a special target system, You
### can set this variable which overrides configure parameters on the
### command line and instead uses the specified options. The variable
### leaves the build-host system untouched.
-### ---------------------------------------------------------------------------
+### ----------------------------------------------------------------------------
erl_xcomp_configure_flags="--without-termcap"
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
### You can specify a specific CC or LD for the build target (the cross
### compiler) here along with magic CFLAGS and/or LDFLAGS if needed
-###----------------------------------------------------------------------------
+### ar and ranlib might also be specified if needed.
+###-----------------------------------------------------------------------------
erl_xcomp_cc="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/ccppc"
@@ -97,9 +64,10 @@ erl_xcomp_cpp="$erl_xcomp_cc $erl_xcomp_cflags -E"
erl_xcomp_ldflags="-mlongcall"
erl_xcomp_ranlib="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/ranlibppc"
+
erl_xcomp_ar="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/arppc"
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
### The ded_ls and ded_ldflags variables control linking of dynamically loaded
### erlang drivers. On i.e. Linux these are set to
### $(CC) and "-shared" respectively, but other OS'es might need other
@@ -107,7 +75,7 @@ erl_xcomp_ar="$WIND_BASE/gnu/3.4.4-vxworks-6.3/$WIND_HOST_TYPE/bin/arppc"
### erl_xcomp_ded_ld_runtime_library_path is the flag to set a
### specific runtime library path for the shared library at link time,
### usually this should be left empty.
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
erl_xcomp_ded_ld=
@@ -115,83 +83,117 @@ erl_xcomp_ded_ldflags=
erl_xcomp_ded_ld_runtime_library_path=
-### The variables in the following section does not need to be set. Only
-### set these if you really know what you are doing.
+###
+### Optional feature, or bug tests
+###
+### These tests cannot (always) be done automatically when cross compiling.
+### You usually does not need to set these variables. Only set these if you
+### really know what you are doing.
###
##
-## Big endian/little endian can usually be determined by configure correctly,
-## but if not, set this variable
-##
+## erl_xcomp_bigendian - yes|no
+## If yes, the target system must be big endian. If no, little endian. This
+## can often be automatically detected, but not always. If not automatically
+## detected, configure will fail unless this variable is set. No default value
+## is used, i.e., configure will try to figure this out automatically.
erl_xcomp_bigendian=yes
##
-## If you have a working poll that can be used: yes|no
+## erl_xcomp_linux_clock_gettime_correction - yes|no (defaults to yes)
+## If yes, clock_gettime(CLOCK_MONOTONIC, _) on the target system must work.
+## This variable is recommended to be set to no on Linux systems with kernel
+## versions less than 2.6.
+##
+erl_xcomp_linux_clock_gettime_correction=
+
+##
+## erl_xcomp_linux_nptl - yes|no (defaults to yes on Linux; otherwise, no)
+## If yes, the target system must have NPTL (Native POSIX Thread Library).
+## Older Linux systems have LinuxThreads instead of NPTL (Linux kernel
+## versions typically less than 2.6).
+##
+erl_xcomp_linux_nptl=
+
+##
+## erl_xcomp_linux_usable_sigusrx - yes|no (defaults to yes)
+## If yes, the SIGUSR1 and SIGUSR2 must be usable by the ERTS. Old
+## LinuxThreads thread libraries (Linux kernel versions less than 2.2) used
+## these signals and made them unusable by the ERTS.
+##
+erl_xcomp_linux_usable_sigusrx=
+
+##
+## erl_xcomp_linux_usable_sigaltstack - yes|no (defaults to yes)
+## If yes, sigaltstack() must be usable on the target system. sigaltstack()
+## on Linux kernel versions less than 2.4 are broken.
+##
+erl_xcomp_linux_usable_sigaltstack=
+
+##
+## erl_xcomp_poll - yes|no (defaults to no on Darwin/MacOSX; otherwise, yes)
+## If yes, the target system must have a working poll() implementation that
+## also can handle devices. If no, select() will be used instead of poll().
##
erl_xcomp_poll=
##
-## If you have a working kqueue() that can be used: yes|no
+## erl_xcomp_kqueue - yes|no (defaults to no)
+## If yes, the target system must have a working kqueue() implementation that
+## returns a file descriptor which can be used by poll() and/or select().
+## If no and the target system has not got epoll() or /dev/poll, the
+## kernel-poll feature will be disabled.
##
erl_xcomp_kqueue=
##
-## If you have a putenv() that stores a copy of the key-value pair: yes|no
+## erl_xcomp_putenv_copy - yes|no (defaults to no)
+## If yes, the target system must have a putenv() implementation that stores a
+## copy of the key/value pair.
##
erl_xcomp_putenv_copy=
##
-## If you have reliable floating point exeptions that can be
-## used: yes|no
+## erl_xcomp_reliable_fpe - yes|no (defaults to no)
+## If yes, the target system must have reliable floating point exceptions.
##
erl_xcomp_reliable_fpe=
##
-## If you have getaddrinfo() usable for ipv6: yes|no
+## erl_xcomp_getaddrinfo - yes|no (defaults to no)
+## If yes, the target system must have a working getaddrinfo() implementation
+## that can handle both IPv4 and IPv6.
##
erl_xcomp_getaddrinfo=
##
-## If you have a gethrvtime() that works and uses ioctl()
-## to /proc/self: yes|no
+## erl_xcomp_gethrvtime_procfs_ioctl - yes|no (defaults to no)
+## If yes, the target system must have a working gethrvtime() implementation
+## and is used with procfs ioctl().
##
erl_xcomp_gethrvtime_procfs_ioctl=
##
-## If you have a working clock_gettime(): yes|no
+## erl_xcomp_clock_gettime - yes|no (defaults to no)
+## If yes, the target system must have a working clock_gettime()
+## implementation that can be used for retrieving process CPU time.
##
erl_xcomp_clock_gettime=
##
-## If you have a __after_morecore_hook that can track malloc()s
-## core memory use: yes|no
+## erl_xcomp_after_morecore_hook - yes|no (defaults to no)
+## If yes, the target system must have a working __after_morecore_hook that
+## can be used for tracking used malloc() implementations core memory usage.
##
erl_xcomp_after_morecore_hook=
##
-## If you have brk, sbrk and end symbols: yes|no
-##
-# brk
-erl_xcomp_have_brk=
-# _brk
-erl_xcomp_have__brk=
-# __brk
-erl_xcomp_have___brk=
-# sbrk
-erl_xcomp_have_sbrk=
-# _sbrk
-erl_xcomp_have__sbrk=
-# __sbrk
-erl_xcomp_have___sbrk=
-# end
-erl_xcomp_end=
-# _end
-erl_xcomp__end=
-
-##
-## If sbrk/brk wrappers using dlsym(RTLD_NEXT, _) can track malloc()s
-## core memory use: yes|no
+## erl_xcomp_dlsym_brk_wrappers - yes|no (defaults to no)
+## If yes, the target system must have a working dlsym(RTLD_NEXT, <S>)
+## implementation that can be used on 'brk' and 'sbrk' symbols used by the
+## malloc() implementation in use, and by this track the malloc()
+## implementations core memory usage.
##
-erl_xcomp_brk_wrappers=
+erl_xcomp_dlsym_brk_wrappers=
### ----------------------------------------------------------------------------
diff --git a/xcomp/erl-xcomp.conf.template b/xcomp/erl-xcomp.conf.template
index cc604a80e5..bed365e754 100644
--- a/xcomp/erl-xcomp.conf.template
+++ b/xcomp/erl-xcomp.conf.template
@@ -31,66 +31,26 @@
###
##
-## Operating system and hardware architecture.
-##
-# Operating system: linux|solaris<ver>|darwin|freebsd|win32|<...>
-erl_xcomp_os=
-# Hardware architecture: x86|x86_64|ultrasparc|sparc64|ppc|arm|tile|<...>
-# Note that this will be the host parameter to configure, so it
-# should be both recognizable by config.sub and a valid prefix for
-# i.e. gcc etc if compiler is not specified further down.
-erl_xcomp_hw=
-# Manufacturer: (unknown is ok)
-erl_xcomp_man=
-# Extra target info (unknown is ok)
-erl_xcomp_target_xtra=
-
-# Target (change if default isn't satisfactory)
-# Note that this has to correspond to what config.sub thinks the machine is.
-# Edit config.sub if not satisfactory, or set this explicitly
-# to what output you will get from running
-# $ERL_TOP/erts/autoconf/config.sub $erl_xcomp_hw
-
-erl_xcomp_target=${erl_xcomp_hw}-${erl_xcomp_man}-${erl_xcomp_os}-${erl_xcomp_target_xtra}
-
-##
-## Sizes (in bytes) of some important types.
-##
-# void *
-erl_xcomp_void_p=
-# short
-erl_xcomp_short=
-# int
-erl_xcomp_int=
-# long
-erl_xcomp_long=
-# long long (use 0 if no 'long long' type exist)
-erl_xcomp_long_long=
-# size_t
-erl_xcomp_sizeof_size_t=
-# off_t
-erl_xcomp_sizeof_off_t=
-
-### ----------------------------------------------------------------------------
-### The variables in the following section have to be set for linux systems
-###
-# linux kernel version (as reported by "uname -r")
-erl_xcomp_linux_kernel=
+## Target system. The value will be passed as '--host' argument to the configure
+## script. It does not have to be a full CPU-VENDOR-OS tripplet, but can be. The
+## full CPU-VENDOR-OS tripplet will be created by:
+## $ERL_TOP/erts/autoconf/config.sub $erl_xcomp_host
+##
+erl_xcomp_host=
### ----------------------------------------------------------------------------
-### ---------------------------------------------------------------------------
### To override the configure flags for a special target system, You
### can set this variable which overrides configure parameters on the
### command line and instead uses the specified options. The variable
### leaves the build-host system untouched.
-### ---------------------------------------------------------------------------
+### ----------------------------------------------------------------------------
erl_xcomp_configure_flags=
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
### You can specify a specific CC or LD for the build target (the cross
### compiler) here along with magic CFLAGS and/or LDFLAGS if needed
### ar and ranlib might also be specified if needed.
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
erl_xcomp_cc=
@@ -106,7 +66,7 @@ erl_xcomp_ranlib=
erl_xcomp_ar=
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
### The ded_ls and ded_ldflags variables control linking of dynamically loaded
### erlang drivers. On i.e. Linux these are set to
### $(CC) and "-shared" respectively, but other OS'es might need other
@@ -114,7 +74,7 @@ erl_xcomp_ar=
### erl_xcomp_ded_ld_runtime_library_path is the flag to set a
### specific runtime library path for the shared library at link time,
### usually this should be left empty.
-###----------------------------------------------------------------------------
+###-----------------------------------------------------------------------------
erl_xcomp_ded_ld=
@@ -122,83 +82,117 @@ erl_xcomp_ded_ldflags=
erl_xcomp_ded_ld_runtime_library_path=
-### The variables in the following section does not need to be set. Only
-### set these if you really know what you are doing.
+###
+### Optional feature, or bug tests
+###
+### These tests cannot (always) be done automatically when cross compiling.
+### You usually does not need to set these variables. Only set these if you
+### really know what you are doing.
###
##
-## Big endian/little endian can usually be determined by configure correctly,
-## but if not, set this variable
-##
+## erl_xcomp_bigendian - yes|no
+## If yes, the target system must be big endian. If no, little endian. This
+## can often be automatically detected, but not always. If not automatically
+## detected, configure will fail unless this variable is set. No default value
+## is used, i.e., configure will try to figure this out automatically.
erl_xcomp_bigendian=
##
-## If you have a working poll that can be used: yes|no
+## erl_xcomp_linux_clock_gettime_correction - yes|no (defaults to yes)
+## If yes, clock_gettime(CLOCK_MONOTONIC, _) on the target system must work.
+## This variable is recommended to be set to no on Linux systems with kernel
+## versions less than 2.6.
+##
+erl_xcomp_linux_clock_gettime_correction=
+
+##
+## erl_xcomp_linux_nptl - yes|no (defaults to yes on Linux; otherwise, no)
+## If yes, the target system must have NPTL (Native POSIX Thread Library).
+## Older Linux systems have LinuxThreads instead of NPTL (Linux kernel
+## versions typically less than 2.6).
+##
+erl_xcomp_linux_nptl=
+
+##
+## erl_xcomp_linux_usable_sigusrx - yes|no (defaults to yes)
+## If yes, the SIGUSR1 and SIGUSR2 must be usable by the ERTS. Old
+## LinuxThreads thread libraries (Linux kernel versions less than 2.2) used
+## these signals and made them unusable by the ERTS.
+##
+erl_xcomp_linux_usable_sigusrx=
+
+##
+## erl_xcomp_linux_usable_sigaltstack - yes|no (defaults to yes)
+## If yes, sigaltstack() must be usable on the target system. sigaltstack()
+## on Linux kernel versions less than 2.4 are broken.
+##
+erl_xcomp_linux_usable_sigaltstack=
+
+##
+## erl_xcomp_poll - yes|no (defaults to no on Darwin/MacOSX; otherwise, yes)
+## If yes, the target system must have a working poll() implementation that
+## also can handle devices. If no, select() will be used instead of poll().
##
erl_xcomp_poll=
##
-## If you have a working kqueue() that can be used: yes|no
+## erl_xcomp_kqueue - yes|no (defaults to no)
+## If yes, the target system must have a working kqueue() implementation that
+## returns a file descriptor which can be used by poll() and/or select().
+## If no and the target system has not got epoll() or /dev/poll, the
+## kernel-poll feature will be disabled.
##
erl_xcomp_kqueue=
##
-## If you have a putenv() that stores a copy of the key-value pair: yes|no
+## erl_xcomp_putenv_copy - yes|no (defaults to no)
+## If yes, the target system must have a putenv() implementation that stores a
+## copy of the key/value pair.
##
erl_xcomp_putenv_copy=
##
-## If you have reliable floating point exeptions that can be
-## used: yes|no
+## erl_xcomp_reliable_fpe - yes|no (defaults to no)
+## If yes, the target system must have reliable floating point exceptions.
##
erl_xcomp_reliable_fpe=
##
-## If you have getaddrinfo() usable for ipv6: yes|no
+## erl_xcomp_getaddrinfo - yes|no (defaults to no)
+## If yes, the target system must have a working getaddrinfo() implementation
+## that can handle both IPv4 and IPv6.
##
erl_xcomp_getaddrinfo=
##
-## If you have a gethrvtime() that works and uses ioctl()
-## to /proc/self: yes|no
+## erl_xcomp_gethrvtime_procfs_ioctl - yes|no (defaults to no)
+## If yes, the target system must have a working gethrvtime() implementation
+## and is used with procfs ioctl().
##
erl_xcomp_gethrvtime_procfs_ioctl=
##
-## If you have a working clock_gettime(): yes|no
+## erl_xcomp_clock_gettime - yes|no (defaults to no)
+## If yes, the target system must have a working clock_gettime()
+## implementation that can be used for retrieving process CPU time.
##
erl_xcomp_clock_gettime=
##
-## If you have a __after_morecore_hook that can track malloc()s
-## core memory use: yes|no
+## erl_xcomp_after_morecore_hook - yes|no (defaults to no)
+## If yes, the target system must have a working __after_morecore_hook that
+## can be used for tracking used malloc() implementations core memory usage.
##
erl_xcomp_after_morecore_hook=
##
-## If you have brk, sbrk and end symbols: yes|no
-##
-# brk
-erl_xcomp_have_brk=
-# _brk
-erl_xcomp_have__brk=
-# __brk
-erl_xcomp_have___brk=
-# sbrk
-erl_xcomp_have_sbrk=
-# _sbrk
-erl_xcomp_have__sbrk=
-# __sbrk
-erl_xcomp_have___sbrk=
-# end
-erl_xcomp_end=
-# _end
-erl_xcomp__end=
-
-##
-## If sbrk/brk wrappers using dlsym(RTLD_NEXT, _) can track malloc()s
-## core memory use: yes|no
+## erl_xcomp_dlsym_brk_wrappers - yes|no (defaults to no)
+## If yes, the target system must have a working dlsym(RTLD_NEXT, <S>)
+## implementation that can be used on 'brk' and 'sbrk' symbols used by the
+## malloc() implementation in use, and by this track the malloc()
+## implementations core memory usage.
##
-erl_xcomp_brk_wrappers=
+erl_xcomp_dlsym_brk_wrappers=
### ----------------------------------------------------------------------------